meerschaum 2.7.9__py3-none-any.whl → 2.8.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. meerschaum/_internal/arguments/_parser.py +17 -5
  2. meerschaum/_internal/term/TermPageHandler.py +1 -1
  3. meerschaum/_internal/term/__init__.py +1 -1
  4. meerschaum/actions/api.py +36 -10
  5. meerschaum/actions/copy.py +3 -1
  6. meerschaum/actions/index.py +1 -1
  7. meerschaum/actions/show.py +7 -7
  8. meerschaum/actions/sync.py +5 -1
  9. meerschaum/actions/verify.py +14 -1
  10. meerschaum/api/__init__.py +77 -41
  11. meerschaum/api/_exceptions.py +18 -0
  12. meerschaum/api/dash/__init__.py +4 -2
  13. meerschaum/api/dash/callbacks/dashboard.py +30 -1
  14. meerschaum/api/dash/components.py +2 -2
  15. meerschaum/api/dash/webterm.py +23 -4
  16. meerschaum/api/models/_pipes.py +8 -8
  17. meerschaum/api/resources/static/css/dash.css +2 -2
  18. meerschaum/api/resources/templates/termpage.html +5 -1
  19. meerschaum/api/routes/__init__.py +15 -12
  20. meerschaum/api/routes/_connectors.py +30 -28
  21. meerschaum/api/routes/_index.py +16 -7
  22. meerschaum/api/routes/_misc.py +30 -22
  23. meerschaum/api/routes/_pipes.py +244 -148
  24. meerschaum/api/routes/_plugins.py +58 -47
  25. meerschaum/api/routes/_users.py +39 -31
  26. meerschaum/api/routes/_version.py +8 -10
  27. meerschaum/api/routes/_webterm.py +2 -2
  28. meerschaum/config/_default.py +10 -0
  29. meerschaum/config/_version.py +1 -1
  30. meerschaum/config/static/__init__.py +5 -2
  31. meerschaum/connectors/api/_APIConnector.py +4 -3
  32. meerschaum/connectors/api/_login.py +21 -17
  33. meerschaum/connectors/api/_pipes.py +1 -0
  34. meerschaum/connectors/api/_request.py +9 -10
  35. meerschaum/connectors/sql/_cli.py +11 -3
  36. meerschaum/connectors/sql/_instance.py +1 -1
  37. meerschaum/connectors/sql/_pipes.py +77 -57
  38. meerschaum/connectors/sql/_sql.py +26 -9
  39. meerschaum/core/Pipe/__init__.py +2 -0
  40. meerschaum/core/Pipe/_attributes.py +13 -2
  41. meerschaum/core/Pipe/_data.py +85 -0
  42. meerschaum/core/Pipe/_deduplicate.py +6 -8
  43. meerschaum/core/Pipe/_sync.py +63 -30
  44. meerschaum/core/Pipe/_verify.py +242 -77
  45. meerschaum/core/User/__init__.py +2 -6
  46. meerschaum/jobs/_Job.py +1 -1
  47. meerschaum/jobs/__init__.py +15 -0
  48. meerschaum/utils/dataframe.py +2 -0
  49. meerschaum/utils/dtypes/sql.py +26 -0
  50. meerschaum/utils/formatting/_pipes.py +1 -1
  51. meerschaum/utils/misc.py +11 -7
  52. meerschaum/utils/packages/_packages.py +1 -1
  53. meerschaum/utils/sql.py +6 -2
  54. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/METADATA +4 -4
  55. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/RECORD +61 -60
  56. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/LICENSE +0 -0
  57. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/NOTICE +0 -0
  58. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/WHEEL +0 -0
  59. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/entry_points.txt +0 -0
  60. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/top_level.txt +0 -0
  61. {meerschaum-2.7.9.dist-info → meerschaum-2.8.0.dist-info}/zip-safe +0 -0
@@ -3,19 +3,19 @@
3
3
  # vim:fenc=utf-8
4
4
 
5
5
  """
6
- Register new Pipes
6
+ Pydantic model for a pipe's keys.
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- from meerschaum.utils.typing import Any, Dict, Optional
11
10
 
12
- from meerschaum.utils.packages import attempt_import
13
- pydantic = attempt_import('pydantic', warn=False)
11
+ import meerschaum as mrsm
12
+ from meerschaum.utils.typing import Optional
13
+
14
+ pydantic = mrsm.attempt_import('pydantic', warn=False, lazy=False)
15
+
14
16
 
15
17
  class MetaPipe(pydantic.BaseModel):
16
- connector_keys: str ### e.g. sql:main
18
+ connector_keys: str
17
19
  metric_key: str
18
20
  location_key: Optional[str] = None
19
- instance: Optional[str] = None
20
-
21
-
21
+ instance_keys: Optional[str] = None
@@ -24,8 +24,8 @@ a {
24
24
  }
25
25
  #webterm-iframe {
26
26
  width: 102%;
27
- height: 85vh !important;
28
- max-height: 85vh;
27
+ height: 83vh !important;
28
+ max-height: 83vh;
29
29
  }
30
30
  .codeblock {
31
31
  background-color: var(--bs-secondary) !important;
@@ -88,7 +88,11 @@ window.addEventListener(
88
88
  if (action_str === "__TMUX_NEW_WINDOW") {
89
89
  line = "\x02:";
90
90
  window.terminal.socket.send(JSON.stringify(["stdin", line]));
91
- line = "new-window python3 -m meerschaum\r";
91
+ line = "new-window python3 -m meerschaum";
92
+ if (instance.length > 0) {
93
+ line += " -i " + instance;
94
+ }
95
+ line += "\r"
92
96
  window.terminal.socket.send(JSON.stringify(["stdin", line]));
93
97
  return;
94
98
  }
@@ -3,17 +3,20 @@
3
3
  # vim:fenc=utf-8
4
4
 
5
5
  """
6
- Import all routes from other modules in package
6
+ Import the routes submodules to register them to the FastAPI app.
7
7
  """
8
8
 
9
- from meerschaum.api.routes._login import *
10
- from meerschaum.api.routes._actions import *
11
- from meerschaum.api.routes._jobs import *
12
- from meerschaum.api.routes._connectors import *
13
- from meerschaum.api.routes._index import *
14
- from meerschaum.api.routes._misc import *
15
- from meerschaum.api.routes._pipes import *
16
- from meerschaum.api.routes._plugins import *
17
- from meerschaum.api.routes._users import *
18
- from meerschaum.api.routes._version import *
19
- from meerschaum.api.routes._webterm import *
9
+ import meerschaum.api.routes._login
10
+ import meerschaum.api.routes._actions
11
+ import meerschaum.api.routes._jobs
12
+ import meerschaum.api.routes._connectors
13
+ import meerschaum.api.routes._index
14
+ import meerschaum.api.routes._misc
15
+ import meerschaum.api.routes._pipes
16
+ import meerschaum.api.routes._plugins
17
+ import meerschaum.api.routes._users
18
+ import meerschaum.api.routes._version
19
+
20
+ from meerschaum.api import _include_dash
21
+ if _include_dash:
22
+ import meerschaum.api.routes._webterm
@@ -7,55 +7,57 @@ Get the currently registered connectors.
7
7
  """
8
8
 
9
9
  import fastapi
10
- from fastapi import Body, HTTPException
11
- from meerschaum.api import app, endpoints, private, no_auth, manager
10
+ from fastapi import HTTPException
11
+
12
+ import meerschaum as mrsm
13
+ from meerschaum.api import app, endpoints, no_auth, manager
12
14
  from meerschaum.utils.typing import Optional, Dict, List, Union
13
15
 
14
16
  endpoint = endpoints['connectors']
15
17
 
18
+
16
19
  @app.get(endpoint, tags=['Connectors'])
17
20
  def get_connectors(
18
- type : Optional[str] = None,
19
- curr_user = (
20
- fastapi.Depends(manager) if not no_auth else None
21
- ),
22
- ) -> Union[Dict[str, List[str]], List[str]]:
21
+ type: Optional[str] = None,
22
+ curr_user = (
23
+ fastapi.Depends(manager) if not no_auth else None
24
+ ),
25
+ ) -> Union[Dict[str, List[str]], List[str]]:
23
26
  """
24
27
  Return the keys of the registered connectors.
25
28
 
26
29
  Parameters
27
30
  ----------
28
- type:
29
- If a `type` is specified, return the list of connectors that belong to that type.
31
+ type: Optional[str], default None
32
+ If provided, return the list of connectors of type `type`.
30
33
  Otherwise, return a dictionary of types that map to lists of labels.
31
- Defaults to `None`.
34
+
35
+ Returns
36
+ -------
37
+ A dictionary of types and labels, or a list of labels.
32
38
  """
33
- from meerschaum.config import get_config
34
- if type is not None and type not in get_config('meerschaum', 'connectors'):
39
+ if type is not None and type not in mrsm.get_config('meerschaum', 'connectors'):
35
40
  raise HTTPException(status_code=404, detail=f"No connectors of type '{type}'.")
36
- types = []
37
- if type is not None:
38
- types.append(type)
39
- else:
40
- for t in get_config('meerschaum', 'connectors'):
41
- types.append(t)
42
-
41
+ types = [type] if type is not None else mrsm.get_config('meerschaum', 'connectors').keys()
43
42
  response_dict = {}
44
- for t in types:
45
- response_dict[t] = list(get_config('meerschaum', 'connectors', t))
46
- if 'default' in response_dict[t]:
47
- response_dict[t].remove('default')
43
+ for typ in types:
44
+ response_dict[typ] = [
45
+ _typ
46
+ for _typ in mrsm.get_config('meerschaum', 'connectors', typ)
47
+ if _typ != 'default'
48
+ ]
48
49
  if type is not None:
49
50
  return response_dict[type]
50
51
  return response_dict
51
52
 
53
+
52
54
  @app.get(endpoint + "/{type}", tags=['Connectors'])
53
55
  def get_connectors_by_type(
54
- type : str,
55
- curr_user = (
56
- fastapi.Depends(manager) if not no_auth else None
57
- ),
58
- ):
56
+ type: str,
57
+ curr_user = (
58
+ fastapi.Depends(manager) if not no_auth else None
59
+ ),
60
+ ):
59
61
  """
60
62
  Convenience method for `get_connectors()`.
61
63
  """
@@ -3,7 +3,7 @@
3
3
  # vim:fenc=utf-8
4
4
 
5
5
  """
6
- Default route
6
+ Redirect the index path to `/dash` if applicable.
7
7
  """
8
8
 
9
9
  import starlette.responses
@@ -12,16 +12,25 @@ from meerschaum.api import (
12
12
  endpoints,
13
13
  HTMLResponse,
14
14
  Request,
15
- version,
15
+ docs_enabled,
16
16
  _include_dash,
17
17
  )
18
- from meerschaum.utils.packages import attempt_import
19
18
  RedirectResponse = starlette.responses.RedirectResponse
20
19
 
20
+ INDEX_REDIRECT_URL: str = (
21
+ endpoints['dash']
22
+ if _include_dash
23
+ else (
24
+ endpoints['docs']
25
+ if docs_enabled
26
+ else endpoints['openapi']
27
+ )
28
+ )
29
+
30
+
21
31
  @app.get(endpoints['index'], response_class=HTMLResponse)
22
- def index(request : Request):
32
+ def index(request: Request):
23
33
  """
24
- Meerschaum WebAPI index page.
34
+ Meerschaum Web API index page.
25
35
  """
26
- _url = endpoints['dash'] if _include_dash else '/docs'
27
- return RedirectResponse(url=_url)
36
+ return RedirectResponse(url=INDEX_REDIRECT_URL)
@@ -7,33 +7,41 @@ Miscellaneous routes
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
- from meerschaum.utils.typing import Dict, Union, Any
11
-
12
10
  import os
11
+
12
+ from meerschaum.utils.typing import Dict, Union, Any, Optional
13
13
  from meerschaum import get_pipes
14
14
  from meerschaum.api import (
15
- app, endpoints, check_allow_chaining, SERVER_ID, debug, get_api_connector,
16
- private, no_auth, manager
15
+ app,
16
+ endpoints,
17
+ check_allow_chaining,
18
+ SERVER_ID,
19
+ debug,
20
+ get_api_connector,
21
+ private,
22
+ manager
17
23
  )
24
+ from meerschaum.config.paths import API_STATIC_PATH
25
+ from meerschaum import __version__ as version
18
26
  import fastapi
19
27
  from starlette.responses import FileResponse, JSONResponse
20
28
  from meerschaum.connectors.poll import _wrap_retry_connect
21
29
 
30
+
22
31
  @app.get(endpoints['favicon'], tags=['Misc'])
23
32
  def get_favicon() -> Any:
24
33
  """
25
34
  Return the favicon file.
26
35
  """
27
- from meerschaum.config._paths import API_STATIC_PATH
28
- return FileResponse(os.path.join(API_STATIC_PATH, 'ico', 'logo.ico'))
36
+ return FileResponse(API_STATIC_PATH / 'ico' / 'logo.ico')
29
37
 
30
38
 
31
39
  @app.get(endpoints['chaining'], tags=['Misc'])
32
40
  def get_chaining_status(
33
- curr_user = (
34
- fastapi.Depends(manager) if private else None
35
- ),
36
- ) -> bool:
41
+ curr_user = (
42
+ fastapi.Depends(manager) if private else None
43
+ ),
44
+ ) -> bool:
37
45
  """
38
46
  Return whether this API instance may be chained.
39
47
  """
@@ -42,17 +50,17 @@ def get_chaining_status(
42
50
 
43
51
  @app.get(endpoints['info'], tags=['Misc'])
44
52
  def get_instance_info(
45
- curr_user = (
46
- fastapi.Depends(manager) if private else None
47
- ),
48
- ) -> Dict[str, Union[str, int]]:
53
+ curr_user = (
54
+ fastapi.Depends(manager) if private else None
55
+ ),
56
+ instance_keys: Optional[str] = None,
57
+ ) -> Dict[str, Union[str, int]]:
49
58
  """
50
59
  Return information about this API instance.
51
60
  """
52
- from meerschaum import __version__ as version
53
- num_plugins = len(get_api_connector().get_plugins(debug=debug))
54
- num_users = len(get_api_connector().get_users(debug=debug))
55
- num_pipes = len(get_pipes(mrsm_instance=get_api_connector(), as_list=True))
61
+ num_plugins = len(get_api_connector(instance_keys).get_plugins(debug=debug))
62
+ num_users = len(get_api_connector(instance_keys).get_users(debug=debug))
63
+ num_pipes = len(get_pipes(mrsm_instance=get_api_connector(instance_keys), as_list=True))
56
64
  return {
57
65
  'version': version,
58
66
  'num_plugins': num_plugins,
@@ -62,14 +70,14 @@ def get_instance_info(
62
70
 
63
71
 
64
72
  @app.get(endpoints['healthcheck'], tags=['Misc'])
65
- def get_healtheck() -> Dict[str, Any]:
73
+ def get_healtheck(instance_keys: Optional[str] = None) -> Dict[str, Any]:
66
74
  """
67
75
  Return a success message to confirm this API is reachable.
68
76
  """
69
- conn = get_api_connector()
77
+ conn = get_api_connector(instance_keys)
70
78
  success = _wrap_retry_connect(
71
79
  conn.meta,
72
- max_retries = 1,
80
+ max_retries=1,
73
81
  )
74
82
  message = "Success" if success else "Failed to connect to instance connector."
75
83
  status_code = 200 if success else 503
@@ -82,7 +90,7 @@ if debug:
82
90
  curr_user = (
83
91
  fastapi.Depends(manager) if private else None
84
92
  ),
85
- ) -> str:
93
+ ) -> Dict[str, Union[int, str]]:
86
94
  return {
87
95
  'server': SERVER_ID,
88
96
  'process': os.getpid(),