haiway 0.10.1__py3-none-any.whl → 0.10.10__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.
haiway/context/access.py CHANGED
@@ -195,6 +195,14 @@ class ScopeContext:
195
195
 
196
196
  @final
197
197
  class ctx:
198
+ @staticmethod
199
+ def trace_id() -> str:
200
+ """
201
+ Get the current context trace identifier.
202
+ """
203
+
204
+ return ScopeIdentifier.current_trace_id()
205
+
198
206
  @staticmethod
199
207
  def scope(
200
208
  label: str,
@@ -1,6 +1,6 @@
1
1
  from contextvars import ContextVar, Token
2
2
  from types import TracebackType
3
- from typing import Self, final
3
+ from typing import Any, Self, final
4
4
  from uuid import uuid4
5
5
 
6
6
  __all__ = [
@@ -12,6 +12,14 @@ __all__ = [
12
12
  class ScopeIdentifier:
13
13
  _context = ContextVar[Self]("ScopeIdentifier")
14
14
 
15
+ @classmethod
16
+ def current_trace_id(cls) -> str:
17
+ try:
18
+ return ScopeIdentifier._context.get().trace_id
19
+
20
+ except LookupError as exc:
21
+ raise RuntimeError("Attempting to access scope identifier outside of scope") from exc
22
+
15
23
  @classmethod
16
24
  def scope(
17
25
  cls,
@@ -60,6 +68,15 @@ class ScopeIdentifier:
60
68
  def __str__(self) -> str:
61
69
  return self.unique_name
62
70
 
71
+ def __eq__(self, other: Any) -> bool:
72
+ if not isinstance(other, self.__class__):
73
+ return False
74
+
75
+ return self.scope_id == other.scope_id and self.trace_id == other.trace_id
76
+
77
+ def __hash__(self) -> int:
78
+ return hash(self.scope_id)
79
+
63
80
  def __enter__(self) -> None:
64
81
  assert not hasattr(self, "_token"), "Context reentrance is not allowed" # nosec: B101
65
82
  self._token: Token[ScopeIdentifier] = ScopeIdentifier._context.set(self)
haiway/helpers/metrics.py CHANGED
@@ -101,6 +101,7 @@ class MetricsHolder:
101
101
  )
102
102
 
103
103
  def __init__(self) -> None:
104
+ self.root_scope: ScopeIdentifier | None = None
104
105
  self.scopes: dict[ScopeIdentifier, MetricsScopeStore] = {}
105
106
 
106
107
  def record(
@@ -109,7 +110,9 @@ class MetricsHolder:
109
110
  /,
110
111
  metric: State,
111
112
  ) -> None:
113
+ assert self.root_scope is not None # nosec: B101
112
114
  assert scope in self.scopes # nosec: B101
115
+
113
116
  metric_type: type[State] = type(metric)
114
117
  metrics: dict[type[State], State] = self.scopes[scope].metrics
115
118
  if (current := metrics.get(metric_type)) and hasattr(current, "__add__"):
@@ -125,6 +128,9 @@ class MetricsHolder:
125
128
  metric: type[Metric],
126
129
  merged: bool,
127
130
  ) -> Metric | None:
131
+ assert self.root_scope is not None # nosec: B101
132
+ assert scope in self.scopes # nosec: B101
133
+
128
134
  if merged:
129
135
  return self.scopes[scope].merged(metric)
130
136
 
@@ -139,7 +145,11 @@ class MetricsHolder:
139
145
  assert scope not in self.scopes # nosec: B101
140
146
  scope_metrics = MetricsScopeStore(scope)
141
147
  self.scopes[scope] = scope_metrics
142
- if not scope.is_root: # root scopes have no actual parent
148
+
149
+ if self.root_scope is None:
150
+ self.root_scope = scope
151
+
152
+ else:
143
153
  for key in self.scopes.keys():
144
154
  if key.scope_id == scope.parent_id:
145
155
  self.scopes[key].nested.append(scope_metrics)
@@ -182,9 +192,10 @@ class MetricsLogger:
182
192
  items_limit: int | None,
183
193
  redact_content: bool,
184
194
  ) -> None:
195
+ self.root_scope: ScopeIdentifier | None = None
196
+ self.scopes: dict[ScopeIdentifier, MetricsScopeStore] = {}
185
197
  self.items_limit: int | None = items_limit
186
198
  self.redact_content: bool = redact_content
187
- self.scopes: dict[ScopeIdentifier, MetricsScopeStore] = {}
188
199
 
189
200
  def record(
190
201
  self,
@@ -192,7 +203,9 @@ class MetricsLogger:
192
203
  /,
193
204
  metric: State,
194
205
  ) -> None:
206
+ assert self.root_scope is not None # nosec: B101
195
207
  assert scope in self.scopes # nosec: B101
208
+
196
209
  metric_type: type[State] = type(metric)
197
210
  metrics: dict[type[State], State] = self.scopes[scope].metrics
198
211
  if (current := metrics.get(metric_type)) and hasattr(current, "__add__"):
@@ -214,6 +227,9 @@ class MetricsLogger:
214
227
  metric: type[Metric],
215
228
  merged: bool,
216
229
  ) -> Metric | None:
230
+ assert self.root_scope is not None # nosec: B101
231
+ assert scope in self.scopes # nosec: B101
232
+
217
233
  if merged:
218
234
  return self.scopes[scope].merged(metric)
219
235
 
@@ -228,7 +244,11 @@ class MetricsLogger:
228
244
  assert scope not in self.scopes # nosec: B101
229
245
  scope_metrics = MetricsScopeStore(scope)
230
246
  self.scopes[scope] = scope_metrics
231
- if not scope.is_root: # root scopes have no actual parent
247
+
248
+ if self.root_scope is None:
249
+ self.root_scope = scope
250
+
251
+ else:
232
252
  for key in self.scopes.keys():
233
253
  if key.scope_id == scope.parent_id:
234
254
  self.scopes[key].nested.append(scope_metrics)
@@ -246,7 +266,7 @@ class MetricsLogger:
246
266
  assert scope in self.scopes # nosec: B101
247
267
  self.scopes[scope].exited = monotonic()
248
268
 
249
- if scope.is_root and self.scopes[scope].finished:
269
+ if scope == self.root_scope and self.scopes[scope].finished:
250
270
  if log := _tree_log(
251
271
  self.scopes[scope],
252
272
  list_items_limit=self.items_limit,
@@ -1,7 +1,9 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: haiway
3
- Version: 0.10.1
3
+ Version: 0.10.10
4
4
  Summary: Framework for dependency injection and state management within structured concurrency model.
5
+ Project-URL: Homepage, https://miquido.com
6
+ Project-URL: Repository, https://github.com/miquido/haiway.git
5
7
  Maintainer-email: Kacper Kaliński <kacper.kalinski@miquido.com>
6
8
  License: MIT License
7
9
 
@@ -24,25 +26,22 @@ License: MIT License
24
26
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
27
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
28
  SOFTWARE.
27
- Project-URL: Homepage, https://miquido.com
28
- Project-URL: Repository, https://github.com/miquido/haiway.git
29
- Classifier: License :: OSI Approved :: MIT License
29
+ License-File: LICENSE
30
30
  Classifier: Intended Audience :: Developers
31
+ Classifier: License :: OSI Approved :: MIT License
31
32
  Classifier: Programming Language :: Python
32
- Classifier: Typing :: Typed
33
33
  Classifier: Topic :: Software Development
34
34
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
35
+ Classifier: Typing :: Typed
35
36
  Requires-Python: >=3.12
36
- Description-Content-Type: text/markdown
37
- License-File: LICENSE
38
37
  Provides-Extra: dev
39
- Requires-Dist: haiway; extra == "dev"
40
- Requires-Dist: ruff~=0.9; extra == "dev"
41
- Requires-Dist: pyright~=1.1; extra == "dev"
42
- Requires-Dist: bandit~=1.7; extra == "dev"
43
- Requires-Dist: pytest~=7.4; extra == "dev"
44
- Requires-Dist: pytest-cov~=4.1; extra == "dev"
45
- Requires-Dist: pytest-asyncio~=0.23; extra == "dev"
38
+ Requires-Dist: bandit~=1.7; extra == 'dev'
39
+ Requires-Dist: pyright~=1.1; extra == 'dev'
40
+ Requires-Dist: pytest-asyncio~=0.23; extra == 'dev'
41
+ Requires-Dist: pytest-cov~=4.1; extra == 'dev'
42
+ Requires-Dist: pytest~=7.4; extra == 'dev'
43
+ Requires-Dist: ruff~=0.9; extra == 'dev'
44
+ Description-Content-Type: text/markdown
46
45
 
47
46
  # 🚗 haiway 🚕 🚚 🚙
48
47
 
@@ -1,9 +1,9 @@
1
1
  haiway/__init__.py,sha256=IEUCyFYKT5IPHnkiUvDVZHdJeHqCaBnG8FhPD20Zgo8,1929
2
2
  haiway/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  haiway/context/__init__.py,sha256=eRvuhifx7xCd-_6desgk55idzNpD5S5sprmCfGb3_9M,662
4
- haiway/context/access.py,sha256=RpTvs7107NoAxCgxxbp7BUThOM9gLXo_Vxv-JgDqW58,16954
4
+ haiway/context/access.py,sha256=Fc2NfoIV2zWE5qPnNgSitK1dy-PME-rJJfUPhoNwJzY,17125
5
5
  haiway/context/disposables.py,sha256=DZjnMp-wMfF-em2Wjhbm1MvXubNpuzFBT70BQNIxC7M,2019
6
- haiway/context/identifier.py,sha256=f5-vZOnhKZmYj__emS51WcgsJqfD_yz6ilr3GUo9z1k,2034
6
+ haiway/context/identifier.py,sha256=Fyb6OHx5FPaSLLRK249HUEr_KlBSG5F-eW01Oxg_Ke8,2570
7
7
  haiway/context/logging.py,sha256=ptwgENuyw-WFgokVsYx9OXZGhJENuO_wgfVjcBryUKM,4251
8
8
  haiway/context/metrics.py,sha256=Ve628X39u0rdLm0vYmVZt7aGeoEeRquR6f67vJIXClY,4213
9
9
  haiway/context/state.py,sha256=LCcFxXqDBu6prvPyPicN-ecONSNHyR56PfQ5u5jNFCU,3000
@@ -12,7 +12,7 @@ haiway/context/types.py,sha256=VvJA7wAPZ3ISpgyThVguioYUXqhHf0XkPfRd0M1ERiQ,142
12
12
  haiway/helpers/__init__.py,sha256=8XRJWNhidWuBKqRZ1Hyc2xqt7DeWLcoOs2V-oexl8VY,579
13
13
  haiway/helpers/asynchrony.py,sha256=9lo9wT3G0TyPb4vfmTnWGBvB_eN6p6nIlj46_9Ag8fQ,6022
14
14
  haiway/helpers/caching.py,sha256=Ok_WE5Whe7XqnIuLZo4rNNBFeWap-aUWX799s4b1JAQ,9536
15
- haiway/helpers/metrics.py,sha256=0CDDEM3QZL35Wc3GteNoAeMuLDehJX06ukxLpNediq0,12813
15
+ haiway/helpers/metrics.py,sha256=0oFBiO-hAzihyC5jvXevNrYOoTcUGc2yGhE1A_866Mc,13314
16
16
  haiway/helpers/retries.py,sha256=gIkyUlqJLDYaxIZd3qzeqGFY9y5Gp8dgZLlZ6hs8hoc,7538
17
17
  haiway/helpers/throttling.py,sha256=zo0OwFq64si5KUwhd58cFHLmGAmYwRbFRJMbv9suhPs,3844
18
18
  haiway/helpers/timeouted.py,sha256=1xU09hQnFdj6p48BwZl5xUvtIr3zC0ZUXehkdrduCjs,3074
@@ -36,8 +36,7 @@ haiway/utils/logs.py,sha256=oDsc1ZdqKDjlTlctLbDcp9iX98Acr-1tdw-Pyg3DElo,1577
36
36
  haiway/utils/mimic.py,sha256=BkVjTVP2TxxC8GChPGyDV6UXVwJmiRiSWeOYZNZFHxs,1828
37
37
  haiway/utils/noop.py,sha256=qgbZlOKWY6_23Zs43OLukK2HagIQKRyR04zrFVm5rWI,344
38
38
  haiway/utils/queue.py,sha256=oQ3GXCJ-PGNtMEr6EPdgqAvYZoj8lAa7Z2drBKBEoBM,2345
39
- haiway-0.10.1.dist-info/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
40
- haiway-0.10.1.dist-info/METADATA,sha256=0m2_QdvBq_XiPN3GiIYFIE0cXf8cVw5esT8kA6_K_5Y,3895
41
- haiway-0.10.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
42
- haiway-0.10.1.dist-info/top_level.txt,sha256=_LdXVLzUzgkvAGQnQJj5kQfoFhpPW6EF4Kj9NapniLg,7
43
- haiway-0.10.1.dist-info/RECORD,,
39
+ haiway-0.10.10.dist-info/METADATA,sha256=PhcebR048J2VPSVrFIQOnQSEIvQpwolFKMmRuOGTWAg,3858
40
+ haiway-0.10.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ haiway-0.10.10.dist-info/licenses/LICENSE,sha256=GehQEW_I1pkmxkkj3NEa7rCTQKYBn7vTPabpDYJlRuo,1063
42
+ haiway-0.10.10.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
@@ -1 +0,0 @@
1
- haiway