haiway 0.25.1__py3-none-any.whl → 0.26.1__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/helpers/tracing.py DELETED
@@ -1,185 +0,0 @@
1
- from asyncio import iscoroutinefunction
2
- from collections.abc import Callable, Coroutine
3
- from typing import Any, cast, overload
4
-
5
- from haiway.context import ctx
6
- from haiway.context.observability import ObservabilityLevel
7
- from haiway.types import MISSING
8
- from haiway.utils import mimic_function
9
- from haiway.utils.formatting import format_str
10
-
11
- __all__ = ("traced",)
12
-
13
-
14
- @overload
15
- def traced[**Args, Result](
16
- function: Callable[Args, Result],
17
- /,
18
- ) -> Callable[Args, Result]: ...
19
-
20
-
21
- @overload
22
- def traced[**Args, Result](
23
- *,
24
- level: ObservabilityLevel = ObservabilityLevel.DEBUG,
25
- label: str,
26
- ) -> Callable[[Callable[Args, Result]], Callable[Args, Result]]: ...
27
-
28
-
29
- def traced[**Args, Result](
30
- function: Callable[Args, Result] | None = None,
31
- /,
32
- *,
33
- level: ObservabilityLevel = ObservabilityLevel.DEBUG,
34
- label: str | None = None,
35
- ) -> Callable[[Callable[Args, Result]], Callable[Args, Result]] | Callable[Args, Result]:
36
- """
37
- Decorator that adds tracing to functions, recording inputs, outputs, and exceptions.
38
-
39
- Automatically records function arguments, return values, and any exceptions
40
- within the current observability context. The recorded data can be used for
41
- debugging, performance analysis, and understanding program execution flow.
42
-
43
- In non-debug builds (when __debug__ is False), this decorator has no effect
44
- and returns the original function to avoid performance impact in production.
45
-
46
- Parameters
47
- ----------
48
- function: Callable[Args, Result] | None
49
- The function to be traced
50
- level: ObservabilityLevel
51
- The observability level at which to record trace information (default: DEBUG)
52
- label: str | None
53
- Custom label for the trace; defaults to the function name if not provided
54
-
55
- Returns
56
- -------
57
- Callable
58
- A decorated function that performs the same operation as the original
59
- but with added tracing
60
-
61
- Notes
62
- -----
63
- Works with both synchronous and asynchronous functions. For asynchronous
64
- functions, properly awaits the result before recording it.
65
- """
66
-
67
- def wrap(
68
- wrapped: Callable[Args, Result],
69
- ) -> Callable[Args, Result]:
70
- if __debug__:
71
- if iscoroutinefunction(wrapped):
72
- return cast(
73
- Callable[Args, Result],
74
- _traced_async(
75
- wrapped,
76
- label=label or wrapped.__name__,
77
- level=level,
78
- ),
79
- )
80
-
81
- else:
82
- return _traced_sync(
83
- wrapped,
84
- label=label or wrapped.__name__,
85
- level=level,
86
- )
87
-
88
- else: # do not trace on non debug runs
89
- return wrapped
90
-
91
- if function := function:
92
- return wrap(wrapped=function)
93
-
94
- else:
95
- return wrap
96
-
97
-
98
- def _traced_sync[**Args, Result](
99
- function: Callable[Args, Result],
100
- /,
101
- label: str,
102
- level: ObservabilityLevel,
103
- ) -> Callable[Args, Result]:
104
- def traced(
105
- *args: Args.args,
106
- **kwargs: Args.kwargs,
107
- ) -> Result:
108
- with ctx.scope(label):
109
- ctx.record(
110
- level,
111
- attributes={
112
- f"[{idx}]": f"{arg}" for idx, arg in enumerate(args) if arg is not MISSING
113
- },
114
- )
115
- ctx.record(
116
- level,
117
- attributes={key: f"{arg}" for key, arg in kwargs.items() if arg is not MISSING},
118
- )
119
-
120
- try:
121
- result: Result = function(*args, **kwargs)
122
- ctx.record(
123
- level,
124
- event="result",
125
- attributes={"value": format_str(result)},
126
- )
127
- return result
128
-
129
- except BaseException as exc:
130
- ctx.record(
131
- level,
132
- event="result",
133
- attributes={"error": f"{type(exc)}: {exc}"},
134
- )
135
- raise exc
136
-
137
- return mimic_function(
138
- function,
139
- within=traced,
140
- )
141
-
142
-
143
- def _traced_async[**Args, Result](
144
- function: Callable[Args, Coroutine[Any, Any, Result]],
145
- /,
146
- label: str,
147
- level: ObservabilityLevel,
148
- ) -> Callable[Args, Coroutine[Any, Any, Result]]:
149
- async def traced(
150
- *args: Args.args,
151
- **kwargs: Args.kwargs,
152
- ) -> Result:
153
- with ctx.scope(label):
154
- ctx.record(
155
- level,
156
- attributes={
157
- f"[{idx}]": f"{arg}" for idx, arg in enumerate(args) if arg is not MISSING
158
- },
159
- )
160
- ctx.record(
161
- level,
162
- attributes={key: f"{arg}" for key, arg in kwargs.items() if arg is not MISSING},
163
- )
164
-
165
- try:
166
- result: Result = await function(*args, **kwargs)
167
- ctx.record(
168
- level,
169
- event="result",
170
- attributes={"value": format_str(result)},
171
- )
172
- return result
173
-
174
- except BaseException as exc:
175
- ctx.record(
176
- level,
177
- event="result",
178
- attributes={"error": f"{type(exc)}: {exc}"},
179
- )
180
- raise exc
181
-
182
- return mimic_function(
183
- function,
184
- within=traced,
185
- )