haiway 0.8.0__tar.gz → 0.8.2__tar.gz
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.
- {haiway-0.8.0/src/haiway.egg-info → haiway-0.8.2}/PKG-INFO +1 -1
- {haiway-0.8.0 → haiway-0.8.2}/pyproject.toml +1 -1
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/metrics.py +62 -53
- {haiway-0.8.0 → haiway-0.8.2/src/haiway.egg-info}/PKG-INFO +1 -1
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_context.py +0 -1
- {haiway-0.8.0 → haiway-0.8.2}/LICENSE +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/README.md +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/setup.cfg +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/access.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/disposables.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/identifier.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/logging.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/metrics.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/state.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/tasks.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/context/types.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/asynchrony.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/caching.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/retries.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/throttling.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/timeouted.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/helpers/tracing.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/py.typed +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/attributes.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/path.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/requirement.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/structure.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/state/validation.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/types/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/types/frozen.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/types/missing.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/__init__.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/always.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/env.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/immutable.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/logs.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/mimic.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/noop.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway/utils/queue.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway.egg-info/SOURCES.txt +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway.egg-info/dependency_links.txt +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway.egg-info/requires.txt +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/src/haiway.egg-info/top_level.txt +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_async_queue.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_attribute_path.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_auto_retry.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_cache.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_state.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_streaming.py +0 -0
- {haiway-0.8.0 → haiway-0.8.2}/tests/test_timeout.py +0 -0
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
5
5
|
[project]
|
6
6
|
name = "haiway"
|
7
7
|
description = "Framework for dependency injection and state management within structured concurrency model."
|
8
|
-
version = "0.8.
|
8
|
+
version = "0.8.2"
|
9
9
|
readme = "README.md"
|
10
10
|
maintainers = [
|
11
11
|
{ name = "Kacper Kaliński", email = "kacper.kalinski@miquido.com" },
|
@@ -59,11 +59,11 @@ class MetricsLogger:
|
|
59
59
|
def handler(
|
60
60
|
cls,
|
61
61
|
items_limit: int | None = None,
|
62
|
-
|
62
|
+
redact_content: bool = False,
|
63
63
|
) -> MetricsHandler:
|
64
64
|
logger_handler: Self = cls(
|
65
65
|
items_limit=items_limit,
|
66
|
-
|
66
|
+
redact_content=redact_content,
|
67
67
|
)
|
68
68
|
return MetricsHandler(
|
69
69
|
record=logger_handler.record,
|
@@ -73,11 +73,11 @@ class MetricsLogger:
|
|
73
73
|
|
74
74
|
def __init__(
|
75
75
|
self,
|
76
|
-
items_limit: int | None
|
77
|
-
|
76
|
+
items_limit: int | None,
|
77
|
+
redact_content: bool,
|
78
78
|
) -> None:
|
79
79
|
self.items_limit: int | None = items_limit
|
80
|
-
self.
|
80
|
+
self.redact_content: bool = redact_content
|
81
81
|
self.scopes: dict[ScopeIdentifier, MetricsScopeStore] = {}
|
82
82
|
|
83
83
|
def record(
|
@@ -93,13 +93,12 @@ class MetricsLogger:
|
|
93
93
|
metrics[type(metric)] = current.__add__(metric) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
|
94
94
|
|
95
95
|
metrics[type(metric)] = metric
|
96
|
-
if
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
):
|
102
|
-
ctx.log_info(f"Recorded:\n• {type(metric).__qualname__}:{log}")
|
96
|
+
if log := _state_log(
|
97
|
+
metric,
|
98
|
+
list_items_limit=self.items_limit,
|
99
|
+
redact_content=self.redact_content,
|
100
|
+
):
|
101
|
+
ctx.log_debug(f"Recorded metric:\n⎡ {type(metric).__qualname__}:{log}\n⌊")
|
103
102
|
|
104
103
|
def enter_scope[Metric: State](
|
105
104
|
self,
|
@@ -107,7 +106,17 @@ class MetricsLogger:
|
|
107
106
|
/,
|
108
107
|
) -> None:
|
109
108
|
assert scope not in self.scopes # nosec: B101
|
110
|
-
|
109
|
+
scope_metrics = MetricsScopeStore(scope)
|
110
|
+
self.scopes[scope] = scope_metrics
|
111
|
+
if not scope.is_root: # root scopes have no actual parent
|
112
|
+
for key in self.scopes.keys():
|
113
|
+
if key.scope_id == scope.parent_id:
|
114
|
+
self.scopes[key].nested.append(scope_metrics)
|
115
|
+
return
|
116
|
+
|
117
|
+
ctx.log_debug(
|
118
|
+
"Attempting to enter nested scope metrics without entering its parent first"
|
119
|
+
)
|
111
120
|
|
112
121
|
def exit_scope[Metric: State](
|
113
122
|
self,
|
@@ -117,22 +126,23 @@ class MetricsLogger:
|
|
117
126
|
assert scope in self.scopes # nosec: B101
|
118
127
|
self.scopes[scope].exited = monotonic()
|
119
128
|
|
120
|
-
if
|
121
|
-
if
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
)
|
127
|
-
ctx.log_info(log)
|
129
|
+
if scope.is_root and self.scopes[scope].finished:
|
130
|
+
if log := _tree_log(
|
131
|
+
self.scopes[scope],
|
132
|
+
list_items_limit=self.items_limit,
|
133
|
+
redact_content=self.redact_content,
|
134
|
+
):
|
135
|
+
ctx.log_debug(f"Metrics summary:\n{log}")
|
128
136
|
|
129
137
|
|
130
138
|
def _tree_log(
|
131
139
|
metrics: MetricsScopeStore,
|
132
140
|
list_items_limit: int | None,
|
133
|
-
|
141
|
+
redact_content: bool,
|
134
142
|
) -> str:
|
135
|
-
log: str =
|
143
|
+
log: str = (
|
144
|
+
f"⎡ @{metrics.identifier.label} [{metrics.identifier.scope_id}]({metrics.time:.2f}s):"
|
145
|
+
)
|
136
146
|
|
137
147
|
for metric in metrics.merged():
|
138
148
|
metric_log: str = ""
|
@@ -140,52 +150,52 @@ def _tree_log(
|
|
140
150
|
if value_log := _value_log(
|
141
151
|
value,
|
142
152
|
list_items_limit=list_items_limit,
|
143
|
-
|
153
|
+
redact_content=redact_content,
|
144
154
|
):
|
145
|
-
metric_log += f"\n
|
155
|
+
metric_log += f"\n├ {key}: {value_log}"
|
146
156
|
|
147
157
|
else:
|
148
|
-
continue # skip
|
158
|
+
continue # skip empty values
|
149
159
|
|
150
160
|
if not metric_log:
|
151
161
|
continue # skip empty logs
|
152
162
|
|
153
|
-
log += f"\n•
|
163
|
+
log += f"\n⎡ •{type(metric).__qualname__}:{metric_log.replace("\n", "\n| ")}\n⌊"
|
154
164
|
|
155
165
|
for nested in metrics.nested:
|
156
166
|
nested_log: str = _tree_log(
|
157
167
|
nested,
|
158
168
|
list_items_limit=list_items_limit,
|
159
|
-
|
160
|
-
)
|
169
|
+
redact_content=redact_content,
|
170
|
+
)
|
161
171
|
|
162
|
-
log += f"\n{nested_log}"
|
172
|
+
log += f"\n\n{nested_log}"
|
163
173
|
|
164
|
-
return log.strip()
|
174
|
+
return log.strip().replace("\n", "\n| ") + "\n⌊"
|
165
175
|
|
166
176
|
|
167
177
|
def _state_log(
|
168
178
|
value: State,
|
169
179
|
/,
|
170
180
|
list_items_limit: int | None,
|
171
|
-
|
181
|
+
redact_content: bool,
|
172
182
|
) -> str | None:
|
173
183
|
state_log: str = ""
|
174
184
|
for key, element in vars(value).items():
|
175
185
|
element_log: str | None = _value_log(
|
176
186
|
element,
|
177
187
|
list_items_limit=list_items_limit,
|
178
|
-
|
188
|
+
redact_content=redact_content,
|
179
189
|
)
|
180
190
|
|
181
191
|
if element_log:
|
182
|
-
state_log += f"\n
|
192
|
+
state_log += f"\n├ {key}: {element_log}"
|
183
193
|
|
184
194
|
else:
|
185
195
|
continue # skip empty logs
|
186
196
|
|
187
197
|
if state_log:
|
188
|
-
return state_log
|
198
|
+
return state_log
|
189
199
|
|
190
200
|
else:
|
191
201
|
return None # skip empty logs
|
@@ -195,17 +205,17 @@ def _dict_log(
|
|
195
205
|
value: dict[Any, Any],
|
196
206
|
/,
|
197
207
|
list_items_limit: int | None,
|
198
|
-
|
208
|
+
redact_content: bool,
|
199
209
|
) -> str | None:
|
200
210
|
dict_log: str = ""
|
201
211
|
for key, element in value.items():
|
202
212
|
element_log: str | None = _value_log(
|
203
213
|
element,
|
204
214
|
list_items_limit=list_items_limit,
|
205
|
-
|
215
|
+
redact_content=redact_content,
|
206
216
|
)
|
207
217
|
if element_log:
|
208
|
-
dict_log += f"\n
|
218
|
+
dict_log += f"\n[{key}]: {element_log}"
|
209
219
|
|
210
220
|
else:
|
211
221
|
continue # skip empty logs
|
@@ -221,7 +231,7 @@ def _list_log(
|
|
221
231
|
value: list[Any],
|
222
232
|
/,
|
223
233
|
list_items_limit: int | None,
|
224
|
-
|
234
|
+
redact_content: bool,
|
225
235
|
) -> str | None:
|
226
236
|
list_log: str = ""
|
227
237
|
enumerated: list[tuple[int, Any]] = list(enumerate(value))
|
@@ -236,10 +246,10 @@ def _list_log(
|
|
236
246
|
element_log: str | None = _value_log(
|
237
247
|
element,
|
238
248
|
list_items_limit=list_items_limit,
|
239
|
-
|
249
|
+
redact_content=redact_content,
|
240
250
|
)
|
241
251
|
if element_log:
|
242
|
-
list_log += f"\n
|
252
|
+
list_log += f"\n[{idx}] {element_log}"
|
243
253
|
|
244
254
|
else:
|
245
255
|
continue # skip empty logs
|
@@ -254,34 +264,33 @@ def _list_log(
|
|
254
264
|
def _raw_value_log(
|
255
265
|
value: Any,
|
256
266
|
/,
|
257
|
-
|
267
|
+
redact_content: bool,
|
258
268
|
) -> str | None:
|
259
269
|
if value is MISSING:
|
260
270
|
return None # skip missing
|
261
271
|
|
262
|
-
|
263
|
-
|
264
|
-
return None # skip empty logs
|
272
|
+
if redact_content:
|
273
|
+
return "[redacted]"
|
265
274
|
|
266
|
-
|
267
|
-
return
|
275
|
+
elif isinstance(value, str):
|
276
|
+
return f'"{value}"'.replace("\n", "\n| ")
|
268
277
|
|
269
278
|
else:
|
270
|
-
return
|
279
|
+
return str(value).strip().replace("\n", "\n| ")
|
271
280
|
|
272
281
|
|
273
282
|
def _value_log(
|
274
283
|
value: Any,
|
275
284
|
/,
|
276
285
|
list_items_limit: int | None,
|
277
|
-
|
286
|
+
redact_content: bool,
|
278
287
|
) -> str | None:
|
279
288
|
# try unpack dicts
|
280
289
|
if isinstance(value, dict):
|
281
290
|
return _dict_log(
|
282
291
|
cast(dict[Any, Any], value),
|
283
292
|
list_items_limit=list_items_limit,
|
284
|
-
|
293
|
+
redact_content=redact_content,
|
285
294
|
)
|
286
295
|
|
287
296
|
# try unpack lists
|
@@ -289,7 +298,7 @@ def _value_log(
|
|
289
298
|
return _list_log(
|
290
299
|
cast(list[Any], value),
|
291
300
|
list_items_limit=list_items_limit,
|
292
|
-
|
301
|
+
redact_content=redact_content,
|
293
302
|
)
|
294
303
|
|
295
304
|
# try unpack state
|
@@ -297,11 +306,11 @@ def _value_log(
|
|
297
306
|
return _state_log(
|
298
307
|
value,
|
299
308
|
list_items_limit=list_items_limit,
|
300
|
-
|
309
|
+
redact_content=redact_content,
|
301
310
|
)
|
302
311
|
|
303
312
|
else:
|
304
313
|
return _raw_value_log(
|
305
314
|
value,
|
306
|
-
|
315
|
+
redact_content=redact_content,
|
307
316
|
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|