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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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(),