paid-python 0.3.0__py3-none-any.whl → 0.3.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.
- paid/tracing/autoinstrumentation.py +5 -29
- paid/tracing/context_data.py +25 -0
- paid/tracing/distributed_tracing.py +1 -1
- paid/tracing/tracing.py +7 -6
- {paid_python-0.3.0.dist-info → paid_python-0.3.1.dist-info}/METADATA +1 -2
- {paid_python-0.3.0.dist-info → paid_python-0.3.1.dist-info}/RECORD +8 -8
- {paid_python-0.3.0.dist-info → paid_python-0.3.1.dist-info}/LICENSE +0 -0
- {paid_python-0.3.0.dist-info → paid_python-0.3.1.dist-info}/WHEEL +0 -0
|
@@ -21,13 +21,6 @@ try:
|
|
|
21
21
|
except ImportError:
|
|
22
22
|
ANTHROPIC_AVAILABLE = False
|
|
23
23
|
|
|
24
|
-
try:
|
|
25
|
-
from opentelemetry.instrumentation.google_generativeai import GoogleGenerativeAiInstrumentor
|
|
26
|
-
|
|
27
|
-
GEMINI_AVAILABLE = True
|
|
28
|
-
except ImportError:
|
|
29
|
-
GEMINI_AVAILABLE = False
|
|
30
|
-
|
|
31
24
|
try:
|
|
32
25
|
from opentelemetry.instrumentation.openai import OpenAIInstrumentor
|
|
33
26
|
|
|
@@ -79,7 +72,6 @@ def paid_autoinstrument(libraries: Optional[List[str]] = None) -> None:
|
|
|
79
72
|
Args:
|
|
80
73
|
libraries: List of library names to instrument. Currently supported:
|
|
81
74
|
- "anthropic": Anthropic library
|
|
82
|
-
- "gemini": Gemini library
|
|
83
75
|
- "openai": OpenAI library
|
|
84
76
|
- "openai-agents": OpenAI Agents SDK
|
|
85
77
|
- "bedrock": AWS Bedrock
|
|
@@ -114,7 +106,7 @@ def paid_autoinstrument(libraries: Optional[List[str]] = None) -> None:
|
|
|
114
106
|
|
|
115
107
|
# Default to all supported libraries if none specified
|
|
116
108
|
if libraries is None:
|
|
117
|
-
libraries = ["anthropic", "
|
|
109
|
+
libraries = ["anthropic", "openai", "openai-agents", "bedrock", "langchain", "google-genai"]
|
|
118
110
|
|
|
119
111
|
for library in libraries:
|
|
120
112
|
if library in _initialized_instrumentors:
|
|
@@ -123,8 +115,6 @@ def paid_autoinstrument(libraries: Optional[List[str]] = None) -> None:
|
|
|
123
115
|
|
|
124
116
|
if library == "anthropic":
|
|
125
117
|
_instrument_anthropic()
|
|
126
|
-
elif library == "gemini":
|
|
127
|
-
_instrument_gemini()
|
|
128
118
|
elif library == "openai":
|
|
129
119
|
_instrument_openai()
|
|
130
120
|
elif library == "openai-agents":
|
|
@@ -158,21 +148,6 @@ def _instrument_anthropic() -> None:
|
|
|
158
148
|
logger.info("Anthropic auto-instrumentation enabled")
|
|
159
149
|
|
|
160
150
|
|
|
161
|
-
def _instrument_gemini() -> None:
|
|
162
|
-
"""
|
|
163
|
-
Instrument the Google Gemini library using opentelemetry-instrumentation-google-generativeai.
|
|
164
|
-
"""
|
|
165
|
-
if not GEMINI_AVAILABLE:
|
|
166
|
-
logger.warning("Gemini library not available, skipping instrumentation")
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
# Instrument Gemini with Paid's tracer provider
|
|
170
|
-
GoogleGenerativeAiInstrumentor().instrument(tracer_provider=tracing.paid_tracer_provider)
|
|
171
|
-
|
|
172
|
-
_initialized_instrumentors.append("gemini")
|
|
173
|
-
logger.info("Gemini auto-instrumentation enabled")
|
|
174
|
-
|
|
175
|
-
|
|
176
151
|
def _instrument_openai() -> None:
|
|
177
152
|
"""
|
|
178
153
|
Instrument the OpenAI library using opentelemetry-instrumentation-openai.
|
|
@@ -227,12 +202,14 @@ def _instrument_langchain() -> None:
|
|
|
227
202
|
return
|
|
228
203
|
|
|
229
204
|
# Instrument LangChain with Paid's tracer provider
|
|
230
|
-
LangchainInstrumentor(disable_trace_context_propagation=True).instrument(
|
|
231
|
-
|
|
205
|
+
LangchainInstrumentor(disable_trace_context_propagation=True).instrument(
|
|
206
|
+
tracer_provider=tracing.paid_tracer_provider
|
|
207
|
+
)
|
|
232
208
|
|
|
233
209
|
_initialized_instrumentors.append("langchain")
|
|
234
210
|
logger.info("LangChain auto-instrumentation enabled")
|
|
235
211
|
|
|
212
|
+
|
|
236
213
|
def _instrument_google_genai() -> None:
|
|
237
214
|
"""
|
|
238
215
|
Instrument Google GenAI using openinference-instrumentation-google-genai.
|
|
@@ -241,7 +218,6 @@ def _instrument_google_genai() -> None:
|
|
|
241
218
|
logger.warning("Google GenAI instrumentation library not available, skipping instrumentation")
|
|
242
219
|
return
|
|
243
220
|
|
|
244
|
-
|
|
245
221
|
GoogleGenAIInstrumentor().instrument(tracer_provider=tracing.paid_tracer_provider)
|
|
246
222
|
_initialized_instrumentors.append("google-genai")
|
|
247
223
|
logger.info("Google GenAI auto-instrumentation enabled")
|
paid/tracing/context_data.py
CHANGED
|
@@ -44,6 +44,8 @@ class ContextData:
|
|
|
44
44
|
|
|
45
45
|
@classmethod
|
|
46
46
|
def set_context_key(cls, key: str, value: Any) -> None:
|
|
47
|
+
if value is None:
|
|
48
|
+
return
|
|
47
49
|
if key not in cls._context:
|
|
48
50
|
logger.warning(f"Invalid context key: {key}")
|
|
49
51
|
return
|
|
@@ -51,6 +53,18 @@ class ContextData:
|
|
|
51
53
|
reset_tokens = cls._get_or_create_reset_tokens()
|
|
52
54
|
reset_tokens[key] = reset_token
|
|
53
55
|
|
|
56
|
+
@classmethod
|
|
57
|
+
def unset_context_key(cls, key: str) -> None:
|
|
58
|
+
"""Unset a specific context key"""
|
|
59
|
+
if key not in cls._context:
|
|
60
|
+
logger.warning(f"Invalid context key: {key}")
|
|
61
|
+
return
|
|
62
|
+
reset_tokens = cls._reset_tokens.get()
|
|
63
|
+
if reset_tokens:
|
|
64
|
+
_ = cls._context[key].set(None)
|
|
65
|
+
if key in reset_tokens:
|
|
66
|
+
del reset_tokens[key]
|
|
67
|
+
|
|
54
68
|
@classmethod
|
|
55
69
|
def reset_context(cls) -> None:
|
|
56
70
|
reset_tokens = cls._reset_tokens.get()
|
|
@@ -58,3 +72,14 @@ class ContextData:
|
|
|
58
72
|
for key, reset_token in reset_tokens.items():
|
|
59
73
|
cls._context[key].reset(reset_token)
|
|
60
74
|
reset_tokens.clear()
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def reset_context_key(cls, key: str) -> None:
|
|
78
|
+
"""Reset a specific context key to its previous value using the stored reset token."""
|
|
79
|
+
if key not in cls._context:
|
|
80
|
+
logger.warning(f"Invalid context key: {key}")
|
|
81
|
+
return
|
|
82
|
+
reset_tokens = cls._reset_tokens.get()
|
|
83
|
+
if reset_tokens and key in reset_tokens:
|
|
84
|
+
cls._context[key].reset(reset_tokens[key])
|
|
85
|
+
del reset_tokens[key]
|
paid/tracing/tracing.py
CHANGED
|
@@ -137,12 +137,11 @@ class PaidSpanProcessor(SpanProcessor):
|
|
|
137
137
|
"""Called to force flush. Always returns True since there's nothing to flush."""
|
|
138
138
|
return True
|
|
139
139
|
|
|
140
|
+
|
|
140
141
|
def setup_graceful_termination():
|
|
141
142
|
def flush_traces():
|
|
142
143
|
try:
|
|
143
|
-
if not isinstance(paid_tracer_provider, NoOpTracerProvider) and not paid_tracer_provider.force_flush(
|
|
144
|
-
10000
|
|
145
|
-
):
|
|
144
|
+
if not isinstance(paid_tracer_provider, NoOpTracerProvider) and not paid_tracer_provider.force_flush(10000):
|
|
146
145
|
logger.error("OTEL force flush : timeout reached")
|
|
147
146
|
except Exception as e:
|
|
148
147
|
logger.error(f"Error flushing traces: {e}")
|
|
@@ -169,8 +168,10 @@ def setup_graceful_termination():
|
|
|
169
168
|
for sig in (signal.SIGINT, signal.SIGTERM):
|
|
170
169
|
signal.signal(sig, create_chained_signal_handler(sig))
|
|
171
170
|
except Exception as e:
|
|
172
|
-
logger.warning(
|
|
173
|
-
|
|
171
|
+
logger.warning(
|
|
172
|
+
f"Could not set up termination handlers: {e}"
|
|
173
|
+
"\nConsider calling initialize_tracing() from the main thread during app initialization if you don't already"
|
|
174
|
+
)
|
|
174
175
|
|
|
175
176
|
|
|
176
177
|
def initialize_tracing(api_key: Optional[str] = None, collector_endpoint: Optional[str] = DEFAULT_COLLECTOR_ENDPOINT):
|
|
@@ -220,7 +221,7 @@ def initialize_tracing(api_key: Optional[str] = None, collector_endpoint: Option
|
|
|
220
221
|
span_processor = SimpleSpanProcessor(otlp_exporter)
|
|
221
222
|
paid_tracer_provider.add_span_processor(span_processor)
|
|
222
223
|
|
|
223
|
-
setup_graceful_termination()
|
|
224
|
+
setup_graceful_termination() # doesn't throw
|
|
224
225
|
|
|
225
226
|
logger.info("Paid tracing initialized successfully - collector at %s", collector_endpoint)
|
|
226
227
|
except Exception as e:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: paid-python
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary:
|
|
5
5
|
Requires-Python: >=3.9,<3.14
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -25,7 +25,6 @@ Requires-Dist: openinference-instrumentation-openai-agents (>=1.0.0)
|
|
|
25
25
|
Requires-Dist: opentelemetry-api (>=1.23.0)
|
|
26
26
|
Requires-Dist: opentelemetry-exporter-otlp-proto-http (>=1.23.0)
|
|
27
27
|
Requires-Dist: opentelemetry-instrumentation-anthropic (>=0.47.0)
|
|
28
|
-
Requires-Dist: opentelemetry-instrumentation-google-generativeai (>=0.47.0)
|
|
29
28
|
Requires-Dist: opentelemetry-instrumentation-langchain (>=0.47.0)
|
|
30
29
|
Requires-Dist: opentelemetry-instrumentation-openai (>=0.47.0)
|
|
31
30
|
Requires-Dist: opentelemetry-sdk (>=1.23.0)
|
|
@@ -37,12 +37,12 @@ paid/orders/lines/raw_client.py,sha256=KZN_yBokCOkf1lUb4ZJtX_NZbqmTqCdJNoaIOdWar
|
|
|
37
37
|
paid/orders/raw_client.py,sha256=650e1Sj2vi9KVJc15M3ENXIKYoth0qMz66dzvXy1Sb4,16245
|
|
38
38
|
paid/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
39
|
paid/tracing/__init__.py,sha256=Pe55koIwqJ6Vv5-9Wqi8xIdwCS2BbxZds-MK5fD-F5Y,506
|
|
40
|
-
paid/tracing/autoinstrumentation.py,sha256=
|
|
41
|
-
paid/tracing/context_data.py,sha256=
|
|
40
|
+
paid/tracing/autoinstrumentation.py,sha256=J1v1YNR6fISd0B-P9MPwWQGVqJ309PuYfaUHsfqGUGk,7650
|
|
41
|
+
paid/tracing/context_data.py,sha256=oiLocz-9qDqB5nQzJlrLsc2Mkr9MaNt_yF_hjppobKc,3298
|
|
42
42
|
paid/tracing/context_manager.py,sha256=ZQtsJ9JPxTwn2t4AW26WpYboaOEZdI2T1Sw0Rwsbf-E,8470
|
|
43
|
-
paid/tracing/distributed_tracing.py,sha256=
|
|
43
|
+
paid/tracing/distributed_tracing.py,sha256=Vht3U8QJmT5jlRVnrybTn-cI1RPuVtyb3V4eTu6gA4g,3991
|
|
44
44
|
paid/tracing/signal.py,sha256=PfYxF6EFQS8j7RY5_C5NXrCBVu9Hq2E2tyG4fdQScJk,3252
|
|
45
|
-
paid/tracing/tracing.py,sha256=
|
|
45
|
+
paid/tracing/tracing.py,sha256=nq3kIoQIJQhzmR9DQy1ayOcOpmDrZzLZc31tjCl0ZiA,14766
|
|
46
46
|
paid/tracing/wrappers/__init__.py,sha256=IIleLB_JUbzLw7FshrU2VHZAKF3dZHMGy1O5zCBwwqM,1588
|
|
47
47
|
paid/tracing/wrappers/anthropic/__init__.py,sha256=_x1fjySAQxuT5cIGO_jU09LiGcZH-WQLqKg8mUFAu2w,115
|
|
48
48
|
paid/tracing/wrappers/anthropic/anthropicWrapper.py,sha256=pGchbOb41CbTxc7H8xXoM-LjR085spqrzXqCVC_rrFk,4913
|
|
@@ -99,7 +99,7 @@ paid/usage/__init__.py,sha256=_VhToAyIt_5axN6CLJwtxg3-CO7THa_23pbUzqhXJa4,85
|
|
|
99
99
|
paid/usage/client.py,sha256=280WJuepoovk3BAVbAx2yN2Q_qBdvx3CcPkLu8lXslc,3030
|
|
100
100
|
paid/usage/raw_client.py,sha256=2acg5C4lxuZodZjepU9QYF0fmBxgG-3ZgXs1zUJG-wM,3709
|
|
101
101
|
paid/version.py,sha256=QIpDFnOrxMxrs86eL0iNH0mSZ1DO078wWHYY9TYAoew,78
|
|
102
|
-
paid_python-0.3.
|
|
103
|
-
paid_python-0.3.
|
|
104
|
-
paid_python-0.3.
|
|
105
|
-
paid_python-0.3.
|
|
102
|
+
paid_python-0.3.1.dist-info/LICENSE,sha256=Nz4baY1zvv0Qy7lqrQtbaiMhmEeGr2Q7A93aqzpml4c,1071
|
|
103
|
+
paid_python-0.3.1.dist-info/METADATA,sha256=1FdLeanO20YNWUwsWdGDasYZdbgSqSSOSLx8tnZxwnI,22335
|
|
104
|
+
paid_python-0.3.1.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
105
|
+
paid_python-0.3.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|