meerschaum 2.9.5__py3-none-any.whl → 3.0.0rc2__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 (158) hide show
  1. meerschaum/__init__.py +5 -2
  2. meerschaum/_internal/__init__.py +1 -0
  3. meerschaum/_internal/arguments/_parse_arguments.py +4 -4
  4. meerschaum/_internal/arguments/_parser.py +19 -2
  5. meerschaum/_internal/docs/index.py +49 -2
  6. meerschaum/_internal/entry.py +6 -6
  7. meerschaum/_internal/shell/Shell.py +1 -1
  8. meerschaum/_internal/static.py +356 -0
  9. meerschaum/actions/api.py +12 -2
  10. meerschaum/actions/bootstrap.py +7 -7
  11. meerschaum/actions/edit.py +142 -18
  12. meerschaum/actions/register.py +137 -6
  13. meerschaum/actions/show.py +117 -29
  14. meerschaum/actions/stop.py +4 -1
  15. meerschaum/actions/sync.py +1 -1
  16. meerschaum/actions/tag.py +9 -8
  17. meerschaum/actions/verify.py +5 -8
  18. meerschaum/api/__init__.py +11 -3
  19. meerschaum/api/_events.py +39 -2
  20. meerschaum/api/_oauth2.py +118 -8
  21. meerschaum/api/_tokens.py +102 -0
  22. meerschaum/api/dash/__init__.py +0 -3
  23. meerschaum/api/dash/callbacks/custom.py +2 -2
  24. meerschaum/api/dash/callbacks/dashboard.py +103 -19
  25. meerschaum/api/dash/callbacks/plugins.py +0 -1
  26. meerschaum/api/dash/callbacks/register.py +1 -1
  27. meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
  28. meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
  29. meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
  30. meerschaum/api/dash/components.py +30 -8
  31. meerschaum/api/dash/keys.py +19 -93
  32. meerschaum/api/dash/pages/dashboard.py +1 -20
  33. meerschaum/api/dash/pages/settings/__init__.py +1 -0
  34. meerschaum/api/dash/pages/settings/password_reset.py +1 -1
  35. meerschaum/api/dash/pages/settings/tokens.py +55 -0
  36. meerschaum/api/dash/pipes.py +94 -59
  37. meerschaum/api/dash/sessions.py +12 -0
  38. meerschaum/api/dash/tokens.py +606 -0
  39. meerschaum/api/dash/websockets.py +1 -1
  40. meerschaum/api/dash/webterm.py +4 -0
  41. meerschaum/api/models/__init__.py +23 -3
  42. meerschaum/api/models/_actions.py +22 -0
  43. meerschaum/api/models/_pipes.py +85 -7
  44. meerschaum/api/models/_tokens.py +81 -0
  45. meerschaum/api/resources/templates/termpage.html +12 -0
  46. meerschaum/api/routes/__init__.py +1 -0
  47. meerschaum/api/routes/_actions.py +3 -4
  48. meerschaum/api/routes/_connectors.py +3 -7
  49. meerschaum/api/routes/_jobs.py +14 -35
  50. meerschaum/api/routes/_login.py +49 -12
  51. meerschaum/api/routes/_misc.py +5 -10
  52. meerschaum/api/routes/_pipes.py +173 -140
  53. meerschaum/api/routes/_plugins.py +38 -28
  54. meerschaum/api/routes/_tokens.py +236 -0
  55. meerschaum/api/routes/_users.py +47 -35
  56. meerschaum/api/routes/_version.py +3 -3
  57. meerschaum/config/__init__.py +43 -20
  58. meerschaum/config/_default.py +43 -6
  59. meerschaum/config/_edit.py +28 -24
  60. meerschaum/config/_environment.py +1 -1
  61. meerschaum/config/_patch.py +6 -6
  62. meerschaum/config/_paths.py +5 -1
  63. meerschaum/config/_read_config.py +65 -34
  64. meerschaum/config/_sync.py +6 -3
  65. meerschaum/config/_version.py +1 -1
  66. meerschaum/config/stack/__init__.py +31 -11
  67. meerschaum/config/static.py +18 -0
  68. meerschaum/connectors/_Connector.py +10 -4
  69. meerschaum/connectors/__init__.py +4 -20
  70. meerschaum/connectors/api/_APIConnector.py +34 -6
  71. meerschaum/connectors/api/_actions.py +2 -2
  72. meerschaum/connectors/api/_jobs.py +1 -1
  73. meerschaum/connectors/api/_login.py +33 -7
  74. meerschaum/connectors/api/_misc.py +2 -2
  75. meerschaum/connectors/api/_pipes.py +16 -31
  76. meerschaum/connectors/api/_plugins.py +2 -2
  77. meerschaum/connectors/api/_request.py +1 -1
  78. meerschaum/connectors/api/_tokens.py +146 -0
  79. meerschaum/connectors/api/_users.py +70 -58
  80. meerschaum/connectors/instance/_InstanceConnector.py +83 -0
  81. meerschaum/connectors/instance/__init__.py +10 -0
  82. meerschaum/connectors/instance/_pipes.py +442 -0
  83. meerschaum/connectors/instance/_plugins.py +151 -0
  84. meerschaum/connectors/instance/_tokens.py +296 -0
  85. meerschaum/connectors/instance/_users.py +181 -0
  86. meerschaum/connectors/parse.py +4 -1
  87. meerschaum/connectors/sql/_SQLConnector.py +8 -5
  88. meerschaum/connectors/sql/_cli.py +12 -11
  89. meerschaum/connectors/sql/_create_engine.py +9 -168
  90. meerschaum/connectors/sql/_fetch.py +2 -18
  91. meerschaum/connectors/sql/_pipes.py +156 -190
  92. meerschaum/connectors/sql/_plugins.py +29 -0
  93. meerschaum/connectors/sql/_sql.py +46 -21
  94. meerschaum/connectors/sql/_users.py +29 -2
  95. meerschaum/connectors/sql/tables/__init__.py +1 -1
  96. meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
  97. meerschaum/connectors/valkey/_pipes.py +53 -26
  98. meerschaum/connectors/valkey/_plugins.py +2 -26
  99. meerschaum/core/Pipe/__init__.py +59 -19
  100. meerschaum/core/Pipe/_attributes.py +412 -90
  101. meerschaum/core/Pipe/_bootstrap.py +54 -24
  102. meerschaum/core/Pipe/_data.py +96 -18
  103. meerschaum/core/Pipe/_dtypes.py +48 -18
  104. meerschaum/core/Pipe/_edit.py +14 -4
  105. meerschaum/core/Pipe/_fetch.py +1 -1
  106. meerschaum/core/Pipe/_show.py +5 -5
  107. meerschaum/core/Pipe/_sync.py +118 -193
  108. meerschaum/core/Pipe/_verify.py +4 -4
  109. meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
  110. meerschaum/core/Plugin/__init__.py +1 -1
  111. meerschaum/core/Token/_Token.py +220 -0
  112. meerschaum/core/Token/__init__.py +12 -0
  113. meerschaum/core/User/_User.py +34 -8
  114. meerschaum/core/User/__init__.py +9 -1
  115. meerschaum/core/__init__.py +1 -0
  116. meerschaum/jobs/_Job.py +3 -2
  117. meerschaum/jobs/__init__.py +3 -2
  118. meerschaum/jobs/systemd.py +1 -1
  119. meerschaum/models/__init__.py +35 -0
  120. meerschaum/models/pipes.py +247 -0
  121. meerschaum/models/tokens.py +38 -0
  122. meerschaum/models/users.py +26 -0
  123. meerschaum/plugins/__init__.py +22 -7
  124. meerschaum/plugins/bootstrap.py +2 -1
  125. meerschaum/utils/_get_pipes.py +68 -27
  126. meerschaum/utils/daemon/Daemon.py +2 -1
  127. meerschaum/utils/daemon/__init__.py +30 -2
  128. meerschaum/utils/dataframe.py +473 -81
  129. meerschaum/utils/debug.py +15 -15
  130. meerschaum/utils/dtypes/__init__.py +473 -34
  131. meerschaum/utils/dtypes/sql.py +368 -28
  132. meerschaum/utils/formatting/__init__.py +1 -1
  133. meerschaum/utils/formatting/_pipes.py +5 -4
  134. meerschaum/utils/formatting/_shell.py +11 -9
  135. meerschaum/utils/misc.py +246 -148
  136. meerschaum/utils/packages/__init__.py +10 -27
  137. meerschaum/utils/packages/_packages.py +41 -34
  138. meerschaum/utils/pipes.py +181 -0
  139. meerschaum/utils/process.py +1 -1
  140. meerschaum/utils/prompt.py +3 -1
  141. meerschaum/utils/schedule.py +2 -1
  142. meerschaum/utils/sql.py +121 -44
  143. meerschaum/utils/typing.py +1 -4
  144. meerschaum/utils/venv/_Venv.py +2 -2
  145. meerschaum/utils/venv/__init__.py +5 -7
  146. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/METADATA +92 -96
  147. meerschaum-3.0.0rc2.dist-info/RECORD +283 -0
  148. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/WHEEL +1 -1
  149. meerschaum-3.0.0rc2.dist-info/licenses/NOTICE +2 -0
  150. meerschaum/api/models/_interfaces.py +0 -15
  151. meerschaum/api/models/_locations.py +0 -15
  152. meerschaum/api/models/_metrics.py +0 -15
  153. meerschaum/config/static/__init__.py +0 -186
  154. meerschaum-2.9.5.dist-info/RECORD +0 -263
  155. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/entry_points.txt +0 -0
  156. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  157. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/top_level.txt +0 -0
  158. {meerschaum-2.9.5.dist-info → meerschaum-3.0.0rc2.dist-info}/zip-safe +0 -0
@@ -0,0 +1,220 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define the properties of a long-lived access token.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import base64
11
+ import uuid
12
+ from random import randint
13
+ from typing import Optional, Union, List, Tuple
14
+ from datetime import datetime, timedelta, timezone
15
+
16
+ import meerschaum as mrsm
17
+
18
+ _PLACEHOLDER_EXPIRATION = datetime(2000, 1, 1)
19
+
20
+ class Token:
21
+ """
22
+ Tokens (long lived access tokens) may be registered and revoked to provide easier authentication (e.g. IoT devices).
23
+ Tokens must be tied to a Meerschaum user account.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ label: Optional[str] = None,
29
+ creation: Optional[datetime] = None,
30
+ expiration: Optional[datetime] = _PLACEHOLDER_EXPIRATION,
31
+ instance: Optional[str] = None,
32
+ user: Optional[mrsm.core.User] = None,
33
+ user_id: Union[int, str, uuid.UUID, None] = None,
34
+ scopes: Optional[List[str]] = None,
35
+ is_valid: bool = True,
36
+ id: Optional[uuid.UUID] = None,
37
+ secret: Optional[str] = None,
38
+ secret_hash: Optional[str] = None,
39
+ ):
40
+ from meerschaum.utils.dtypes import coerce_timezone, round_time
41
+ from meerschaum.utils.daemon import get_new_daemon_name
42
+ from meerschaum._internal.static import STATIC_CONFIG
43
+ now = datetime.now(timezone.utc)
44
+ default_expiration_days = mrsm.get_config(
45
+ 'system', 'api', 'tokens', 'default_expiration_days',
46
+ ) or 366
47
+ default_expiration = round_time(
48
+ now + timedelta(days=default_expiration_days),
49
+ timedelta(days=1),
50
+ )
51
+ if expiration == _PLACEHOLDER_EXPIRATION:
52
+ expiration = default_expiration
53
+ self.creation = coerce_timezone(creation) if creation is not None else None
54
+ self.expiration = coerce_timezone(expiration) if expiration is not None else None
55
+ self._instance_keys = str(instance) if instance is not None else None
56
+ self.label = label or get_new_daemon_name()
57
+ self._user = user
58
+ self._user_id = user_id
59
+ self.scopes = scopes or list(STATIC_CONFIG['tokens']['scopes'])
60
+ self.is_valid = is_valid
61
+ self.id = id
62
+ self.secret = secret
63
+ self.secret_hash = secret_hash
64
+
65
+ def generate_credentials(self) -> Tuple[uuid.UUID, str]:
66
+ """
67
+ Generate and return the client ID and secret values for this token.
68
+ """
69
+ if self.id and self.secret:
70
+ return self.id, self.secret
71
+
72
+ from meerschaum.utils.misc import generate_password
73
+ from meerschaum._internal.static import STATIC_CONFIG
74
+ min_len = STATIC_CONFIG['tokens']['minimum_length']
75
+ max_len = STATIC_CONFIG['tokens']['maximum_length']
76
+
77
+ secret_len = randint(min_len, max_len + 1)
78
+ self.secret = generate_password(secret_len)
79
+ self.id = uuid.uuid4()
80
+ return self.id, self.secret
81
+
82
+ def get_api_key(self) -> str:
83
+ """
84
+ Return the API key to be sent in the `Authorization` header.
85
+ """
86
+ return 'mrsm-key:' + base64.b64encode(f"{self.id}:{self.secret}".encode('utf-8')).decode('utf-8')
87
+
88
+ @property
89
+ def instance_connector(self) -> mrsm.connectors.InstanceConnector:
90
+ """
91
+ Return the instance connector to use for this token.
92
+ """
93
+ from meerschaum.connectors.parse import parse_instance_keys
94
+ return parse_instance_keys(self._instance_keys)
95
+
96
+ @property
97
+ def user(self) -> Union[mrsm.core.User, None]:
98
+ """
99
+ Return the `User` for this token.
100
+ """
101
+ if self._user is not None:
102
+ return self._user
103
+
104
+ if self._user_id is not None:
105
+ username = self.instance_connector.get_username(self._user_id)
106
+ if not username:
107
+ return None
108
+ _user = mrsm.core.User(
109
+ username,
110
+ user_id=self._user_id,
111
+ instance=str(self.instance_connector),
112
+ )
113
+ self._user = _user
114
+ return _user
115
+
116
+ return None
117
+
118
+ def register(self, debug: bool = False) -> mrsm.SuccessTuple:
119
+ """
120
+ Register the new token to the configured instance.
121
+ """
122
+ if self.user is None:
123
+ raise ValueError("Cannot register a token with a user.")
124
+
125
+ return self.instance_connector.register_token(self, debug=debug)
126
+
127
+ def edit(self, debug: bool = False) -> mrsm.SuccessTuple:
128
+ """
129
+ Edit some of the token's attributes (expiration, scopes).
130
+ """
131
+ return self.instance_connector.edit_token(self, debug=debug)
132
+
133
+ def invalidate(self, debug: bool = False) -> mrsm.SuccessTuple:
134
+ """
135
+ Set `is_valid` to False for this token.
136
+ """
137
+ self.is_valid = False
138
+ return self.instance_connector.invalidate_token(self, debug=debug)
139
+
140
+ def delete(self, debug: bool = False) -> mrsm.SuccessTuple:
141
+ """
142
+ Delete this token from the instance connector.
143
+ """
144
+ return self.instance_connector.delete_token(self, debug=debug)
145
+
146
+ def exists(self, debug: bool = False) -> bool:
147
+ """
148
+ Return `True` if a token's ID exists in the tokens pipe.
149
+ """
150
+ if not self.id:
151
+ return False
152
+ return self.instance_connector.token_exists(self.id, debug=debug)
153
+
154
+ def to_model(self, refresh: bool = False, debug: bool = False) -> 'TokenModel':
155
+ """
156
+ Export the current state to a `TokenModel`.
157
+ """
158
+ from meerschaum.models import TokenModel
159
+ in_memory_doc = {
160
+ 'id': self.id,
161
+ 'label': self.label,
162
+ 'creation': self.creation,
163
+ 'expiration': self.expiration,
164
+ 'is_valid': self.is_valid,
165
+ 'user_id': self._user_id,
166
+ 'scopes': self.scopes,
167
+ }
168
+ if not refresh:
169
+ return TokenModel(**in_memory_doc)
170
+
171
+ if not self.id:
172
+ raise ValueError(f"ID is not set for {self}.")
173
+
174
+ token_model = self.instance_connector.get_token_model(self.id, debug=debug)
175
+ if token_model is None:
176
+ raise ValueError(f"{self} does not exist on instance '{self.instance_connector}'.")
177
+
178
+ return token_model
179
+
180
+ def get_scopes(self, refresh: bool = False, debug: bool = False) -> List[str]:
181
+ """
182
+ Return the scopes for this `Token`.
183
+ """
184
+ if not refresh:
185
+ return self.scopes
186
+
187
+ self.scopes = self.instance_connector.get_token_scopes(self, debug=debug)
188
+ return self.scopes
189
+
190
+ def get_expiration_status(self, debug: bool = False) -> bool:
191
+ """
192
+ Check the token's expiration against the current timestamp.
193
+ If it's expired, invalidate the token.
194
+
195
+ Returns
196
+ -------
197
+ A bool to indication whether the token has expired.
198
+ A value of `True` means the token is invalid,
199
+ and `False` indicates a valid token.
200
+ """
201
+ expiration = self.expiration
202
+ if expiration is None:
203
+ return False
204
+
205
+ now = datetime.now(timezone.utc)
206
+ is_expired = expiration <= now
207
+ if is_expired:
208
+ self.is_valid = False
209
+ invalidate_success, invalidate_msg = self.invalidate(debug=debug)
210
+ if not invalidate_success:
211
+ from meerschaum.utils.warnings import warn
212
+ warn(f"Failed to invalidate {self}:\n{invalidate_msg}")
213
+
214
+ return is_expired
215
+
216
+ def __str__(self):
217
+ return self.label
218
+
219
+ def __repr__(self):
220
+ return self.to_model(refresh=False).__repr__().replace('TokenModel(', 'Token(')
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define the components of long-lived access tokens.
6
+ """
7
+
8
+ from meerschaum.core.Token._Token import Token
9
+
10
+ __all__ = (
11
+ 'Token',
12
+ )
@@ -7,14 +7,15 @@ User class definition
7
7
  """
8
8
 
9
9
  from __future__ import annotations
10
+
10
11
  import os
11
12
  import hashlib
12
13
  import hmac
14
+ import uuid
13
15
  from binascii import b2a_base64, a2b_base64, Error as _BinAsciiError
14
16
 
15
17
  import meerschaum as mrsm
16
- from meerschaum.utils.typing import Optional, Dict, Any, Union
17
- from meerschaum.config.static import STATIC_CONFIG
18
+ from meerschaum.utils.typing import Optional, Dict, Any, Union, List
18
19
  from meerschaum.utils.warnings import warn
19
20
 
20
21
 
@@ -40,7 +41,7 @@ def hash_password(
40
41
 
41
42
  rounds: Optional[int], default None
42
43
  If provided, use this number of rounds to generate the hash.
43
- Defaults to 3,000,000.
44
+ Defaults to 1,000,000.
44
45
 
45
46
  Returns
46
47
  -------
@@ -48,6 +49,7 @@ def hash_password(
48
49
  See the `passlib` documentation on the string format:
49
50
  https://passlib.readthedocs.io/en/stable/lib/passlib.hash.pbkdf2_digest.html#format-algorithm
50
51
  """
52
+ from meerschaum._internal.static import STATIC_CONFIG
51
53
  hash_config = STATIC_CONFIG['users']['password_hash']
52
54
  if password is None:
53
55
  password = ''
@@ -64,7 +66,7 @@ def hash_password(
64
66
  )
65
67
  return (
66
68
  f"$pbkdf2-{hash_config['algorithm_name']}"
67
- + f"${hash_config['pbkdf2_sha256__default_rounds']}"
69
+ + f"${rounds}"
68
70
  + '$' + ab64_encode(salt).decode('utf-8')
69
71
  + '$' + ab64_encode(pw_hash).decode('utf-8')
70
72
  )
@@ -89,6 +91,7 @@ def verify_password(
89
91
  -------
90
92
  A `bool` indicating whether `password` matches `password_hash`.
91
93
  """
94
+ from meerschaum._internal.static import STATIC_CONFIG
92
95
  if password is None or password_hash is None:
93
96
  return False
94
97
  hash_config = STATIC_CONFIG['users']['password_hash']
@@ -177,7 +180,7 @@ class User:
177
180
  type: Optional[str] = None,
178
181
  email: Optional[str] = None,
179
182
  attributes: Optional[Dict[str, Any]] = None,
180
- user_id: Optional[int] = None,
183
+ user_id: Union[int, str, uuid.UUID, None] = None,
181
184
  instance: Optional[str] = None
182
185
  ):
183
186
  if password is None:
@@ -188,7 +191,7 @@ class User:
188
191
  self.type = type
189
192
  self._attributes = attributes
190
193
  self._user_id = user_id
191
- self._instance_keys = str(instance)
194
+ self._instance_keys = str(instance) if instance is not None else None
192
195
 
193
196
  def __repr__(self):
194
197
  return str(self)
@@ -203,14 +206,14 @@ class User:
203
206
  return self._attributes
204
207
 
205
208
  @property
206
- def instance_connector(self) -> 'mrsm.connectors.Connector':
209
+ def instance_connector(self) -> mrsm.connectors.InstanceConnector:
207
210
  from meerschaum.connectors.parse import parse_instance_keys
208
211
  if '_instance_connector' not in self.__dict__:
209
212
  self._instance_connector = parse_instance_keys(self._instance_keys)
210
213
  return self._instance_connector
211
214
 
212
215
  @property
213
- def user_id(self) -> Union[int, str, None]:
216
+ def user_id(self) -> Union[int, str, uuid.UUID, None]:
214
217
  """NOTE: This causes recursion with the API,
215
218
  so don't try to get fancy with read-only attributes.
216
219
  """
@@ -231,3 +234,26 @@ class User:
231
234
 
232
235
  self._password_hash = hash_password(self.password)
233
236
  return self._password_hash
237
+
238
+ def get_attributes(self, refresh: bool = False, debug: bool = False) -> Dict[str, Any]:
239
+ """
240
+ Return the user's attributes.
241
+ """
242
+ if not refresh:
243
+ return self.attributes
244
+ self._attributes = self.instance_connector.get_user_attributes(self, debug=debug) or {}
245
+ return self._attributes
246
+
247
+ def get_scopes(self, refresh: bool = False, debug: bool = False) -> List[str]:
248
+ """
249
+ Return the scopes for this user.
250
+ """
251
+ from meerschaum._internal.static import STATIC_CONFIG
252
+ _attributes = self.get_attributes(refresh=refresh, debug=debug)
253
+ return _attributes.get('scopes', None) or list(STATIC_CONFIG['tokens']['scopes'])
254
+
255
+ def register(self, debug: bool = False, **kwargs: Any) -> mrsm.SuccessTuple:
256
+ """
257
+ Register a user to the instance connector.
258
+ """
259
+ return self.instance_connector.register_user(self, debug=debug, **kwargs)
@@ -9,7 +9,15 @@ Manager users' metadata via the User class
9
9
  from typing import Optional
10
10
 
11
11
  import meerschaum as mrsm
12
- from meerschaum.core.User._User import User
12
+ from meerschaum.core.User._User import User, hash_password, verify_password
13
+
14
+
15
+ __all__ = (
16
+ 'User',
17
+ 'hash_password',
18
+ 'verify_password',
19
+ 'is_user_allowed_to_execute',
20
+ )
13
21
 
14
22
 
15
23
  def is_user_allowed_to_execute(
@@ -9,3 +9,4 @@ Import the core class definitions into the parent module.
9
9
  from meerschaum.core.Pipe import Pipe
10
10
  from meerschaum.core.Plugin import Plugin
11
11
  from meerschaum.core.User import User
12
+ from meerschaum.core.Token import Token
meerschaum/jobs/_Job.py CHANGED
@@ -24,7 +24,7 @@ from meerschaum._internal.entry import entry
24
24
  from meerschaum.utils.warnings import warn
25
25
  from meerschaum.config.paths import LOGS_RESOURCES_PATH
26
26
  from meerschaum.config import get_config
27
- from meerschaum.config.static import STATIC_CONFIG
27
+ from meerschaum._internal.static import STATIC_CONFIG
28
28
 
29
29
  if TYPE_CHECKING:
30
30
  from meerschaum.jobs._Executor import Executor
@@ -702,7 +702,8 @@ class Job:
702
702
 
703
703
  _result = self.daemon.properties.get('result', None)
704
704
  if _result is None:
705
- return False, "No result available."
705
+ from meerschaum.utils.daemon.Daemon import _results
706
+ return _results.get(self.daemon.daemon_id, (False, "No result available."))
706
707
 
707
708
  return tuple(_result)
708
709
 
@@ -79,7 +79,8 @@ def get_jobs(
79
79
  }
80
80
 
81
81
  def _get_systemd_jobs():
82
- conn = mrsm.get_connector('systemd')
82
+ from meerschaum.jobs.systemd import SystemdExecutor
83
+ conn = SystemdExecutor('systemd')
83
84
  jobs = conn.get_jobs(debug=debug)
84
85
  return {
85
86
  name: job
@@ -369,7 +370,7 @@ def start_check_jobs_thread():
369
370
  import atexit
370
371
  from functools import partial
371
372
  from meerschaum.utils.threading import RepeatTimer
372
- from meerschaum.config.static import STATIC_CONFIG
373
+ from meerschaum._internal.static import STATIC_CONFIG
373
374
 
374
375
  global _check_loop_stop_thread
375
376
  sleep_seconds = STATIC_CONFIG['jobs']['check_restart_seconds']
@@ -21,7 +21,7 @@ import meerschaum as mrsm
21
21
  from meerschaum.jobs import Job, Executor, make_executor
22
22
  from meerschaum.utils.typing import Dict, Any, List, SuccessTuple, Union, Optional, Callable
23
23
  from meerschaum.config import get_config
24
- from meerschaum.config.static import STATIC_CONFIG
24
+ from meerschaum._internal.static import STATIC_CONFIG
25
25
  from meerschaum.utils.warnings import warn, dprint
26
26
  from meerschaum._internal.arguments._parse_arguments import parse_arguments
27
27
 
@@ -0,0 +1,35 @@
1
+ #! /usr/bin/env python3
2
+ # vim:fenc=utf-8
3
+
4
+ """
5
+ Define fundamental Pydantic models (to be built upon for API response models).
6
+ """
7
+
8
+ import meerschaum as mrsm
9
+
10
+ annotated_types = mrsm.attempt_import('annotated_types', lazy=False)
11
+ pydantic = mrsm.attempt_import('pydantic', lazy=False)
12
+
13
+ from meerschaum.models.pipes import (
14
+ PipeModel,
15
+ PipeWithParametersModel,
16
+ PipesWithParametersDictModel,
17
+ ConnectorKeysModel,
18
+ MetricKeyModel,
19
+ LocationKeyModel,
20
+ InstanceKeysModel,
21
+ )
22
+ from meerschaum.models.users import UserModel
23
+ from meerschaum.models.tokens import TokenModel
24
+
25
+ __all__ = (
26
+ 'PipeModel',
27
+ 'PipeWithParametersModel',
28
+ 'PipesWithParametersDictModel',
29
+ 'ConnectorKeysModel',
30
+ 'MetricKeyModel',
31
+ 'LocationKeyModel',
32
+ 'InstanceKeysModel',
33
+ 'UserModel',
34
+ 'TokenModel',
35
+ )