openlit 1.34.30__py3-none-any.whl → 1.34.31__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.
- openlit/__helpers.py +235 -86
- openlit/__init__.py +16 -13
- openlit/_instrumentors.py +2 -1
- openlit/evals/all.py +50 -21
- openlit/evals/bias_detection.py +47 -20
- openlit/evals/hallucination.py +53 -22
- openlit/evals/toxicity.py +50 -21
- openlit/evals/utils.py +54 -30
- openlit/guard/all.py +61 -19
- openlit/guard/prompt_injection.py +34 -14
- openlit/guard/restrict_topic.py +46 -15
- openlit/guard/sensitive_topic.py +34 -14
- openlit/guard/utils.py +58 -22
- openlit/instrumentation/ag2/__init__.py +24 -8
- openlit/instrumentation/ag2/ag2.py +34 -13
- openlit/instrumentation/ag2/async_ag2.py +34 -13
- openlit/instrumentation/ag2/utils.py +133 -30
- openlit/instrumentation/ai21/__init__.py +43 -14
- openlit/instrumentation/ai21/ai21.py +47 -21
- openlit/instrumentation/ai21/async_ai21.py +47 -21
- openlit/instrumentation/ai21/utils.py +299 -78
- openlit/instrumentation/anthropic/__init__.py +21 -4
- openlit/instrumentation/anthropic/anthropic.py +28 -17
- openlit/instrumentation/anthropic/async_anthropic.py +28 -17
- openlit/instrumentation/anthropic/utils.py +145 -35
- openlit/instrumentation/assemblyai/__init__.py +11 -2
- openlit/instrumentation/assemblyai/assemblyai.py +15 -4
- openlit/instrumentation/assemblyai/utils.py +120 -25
- openlit/instrumentation/astra/__init__.py +43 -10
- openlit/instrumentation/astra/astra.py +28 -5
- openlit/instrumentation/astra/async_astra.py +28 -5
- openlit/instrumentation/astra/utils.py +151 -55
- openlit/instrumentation/azure_ai_inference/__init__.py +43 -10
- openlit/instrumentation/azure_ai_inference/async_azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/azure_ai_inference.py +53 -21
- openlit/instrumentation/azure_ai_inference/utils.py +307 -83
- openlit/instrumentation/bedrock/__init__.py +21 -4
- openlit/instrumentation/bedrock/bedrock.py +63 -25
- openlit/instrumentation/bedrock/utils.py +139 -30
- openlit/instrumentation/chroma/__init__.py +89 -16
- openlit/instrumentation/chroma/chroma.py +28 -6
- openlit/instrumentation/chroma/utils.py +167 -51
- openlit/instrumentation/cohere/__init__.py +63 -18
- openlit/instrumentation/cohere/async_cohere.py +63 -24
- openlit/instrumentation/cohere/cohere.py +63 -24
- openlit/instrumentation/cohere/utils.py +286 -73
- openlit/instrumentation/controlflow/__init__.py +35 -9
- openlit/instrumentation/controlflow/controlflow.py +66 -33
- openlit/instrumentation/crawl4ai/__init__.py +25 -10
- openlit/instrumentation/crawl4ai/async_crawl4ai.py +78 -31
- openlit/instrumentation/crawl4ai/crawl4ai.py +78 -31
- openlit/instrumentation/crewai/__init__.py +40 -15
- openlit/instrumentation/crewai/async_crewai.py +32 -7
- openlit/instrumentation/crewai/crewai.py +32 -7
- openlit/instrumentation/crewai/utils.py +159 -56
- openlit/instrumentation/dynamiq/__init__.py +46 -12
- openlit/instrumentation/dynamiq/dynamiq.py +74 -33
- openlit/instrumentation/elevenlabs/__init__.py +23 -4
- openlit/instrumentation/elevenlabs/async_elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/elevenlabs.py +16 -4
- openlit/instrumentation/elevenlabs/utils.py +128 -25
- openlit/instrumentation/embedchain/__init__.py +11 -2
- openlit/instrumentation/embedchain/embedchain.py +68 -35
- openlit/instrumentation/firecrawl/__init__.py +24 -7
- openlit/instrumentation/firecrawl/firecrawl.py +46 -20
- openlit/instrumentation/google_ai_studio/__init__.py +45 -10
- openlit/instrumentation/google_ai_studio/async_google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/google_ai_studio.py +67 -44
- openlit/instrumentation/google_ai_studio/utils.py +180 -67
- openlit/instrumentation/gpt4all/__init__.py +22 -7
- openlit/instrumentation/gpt4all/gpt4all.py +67 -29
- openlit/instrumentation/gpt4all/utils.py +285 -61
- openlit/instrumentation/gpu/__init__.py +128 -47
- openlit/instrumentation/groq/__init__.py +21 -4
- openlit/instrumentation/groq/async_groq.py +33 -21
- openlit/instrumentation/groq/groq.py +33 -21
- openlit/instrumentation/groq/utils.py +192 -55
- openlit/instrumentation/haystack/__init__.py +70 -24
- openlit/instrumentation/haystack/async_haystack.py +28 -6
- openlit/instrumentation/haystack/haystack.py +28 -6
- openlit/instrumentation/haystack/utils.py +196 -74
- openlit/instrumentation/julep/__init__.py +69 -19
- openlit/instrumentation/julep/async_julep.py +53 -27
- openlit/instrumentation/julep/julep.py +53 -28
- openlit/instrumentation/langchain/__init__.py +74 -63
- openlit/instrumentation/langchain/callback_handler.py +1100 -0
- openlit/instrumentation/langchain_community/__init__.py +13 -2
- openlit/instrumentation/langchain_community/async_langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/langchain_community.py +23 -5
- openlit/instrumentation/langchain_community/utils.py +35 -9
- openlit/instrumentation/letta/__init__.py +68 -15
- openlit/instrumentation/letta/letta.py +99 -54
- openlit/instrumentation/litellm/__init__.py +43 -14
- openlit/instrumentation/litellm/async_litellm.py +51 -26
- openlit/instrumentation/litellm/litellm.py +51 -26
- openlit/instrumentation/litellm/utils.py +304 -102
- openlit/instrumentation/llamaindex/__init__.py +267 -90
- openlit/instrumentation/llamaindex/async_llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/llamaindex.py +28 -6
- openlit/instrumentation/llamaindex/utils.py +204 -91
- openlit/instrumentation/mem0/__init__.py +11 -2
- openlit/instrumentation/mem0/mem0.py +50 -29
- openlit/instrumentation/milvus/__init__.py +10 -2
- openlit/instrumentation/milvus/milvus.py +31 -6
- openlit/instrumentation/milvus/utils.py +166 -67
- openlit/instrumentation/mistral/__init__.py +63 -18
- openlit/instrumentation/mistral/async_mistral.py +63 -24
- openlit/instrumentation/mistral/mistral.py +63 -24
- openlit/instrumentation/mistral/utils.py +277 -69
- openlit/instrumentation/multion/__init__.py +69 -19
- openlit/instrumentation/multion/async_multion.py +57 -26
- openlit/instrumentation/multion/multion.py +57 -26
- openlit/instrumentation/ollama/__init__.py +39 -18
- openlit/instrumentation/ollama/async_ollama.py +57 -26
- openlit/instrumentation/ollama/ollama.py +57 -26
- openlit/instrumentation/ollama/utils.py +226 -50
- openlit/instrumentation/openai/__init__.py +156 -32
- openlit/instrumentation/openai/async_openai.py +147 -67
- openlit/instrumentation/openai/openai.py +150 -67
- openlit/instrumentation/openai/utils.py +657 -185
- openlit/instrumentation/openai_agents/__init__.py +5 -1
- openlit/instrumentation/openai_agents/processor.py +110 -90
- openlit/instrumentation/phidata/__init__.py +13 -5
- openlit/instrumentation/phidata/phidata.py +67 -32
- openlit/instrumentation/pinecone/__init__.py +48 -9
- openlit/instrumentation/pinecone/async_pinecone.py +27 -5
- openlit/instrumentation/pinecone/pinecone.py +27 -5
- openlit/instrumentation/pinecone/utils.py +153 -47
- openlit/instrumentation/premai/__init__.py +22 -7
- openlit/instrumentation/premai/premai.py +51 -26
- openlit/instrumentation/premai/utils.py +246 -59
- openlit/instrumentation/pydantic_ai/__init__.py +49 -22
- openlit/instrumentation/pydantic_ai/pydantic_ai.py +69 -16
- openlit/instrumentation/pydantic_ai/utils.py +89 -24
- openlit/instrumentation/qdrant/__init__.py +19 -4
- openlit/instrumentation/qdrant/async_qdrant.py +33 -7
- openlit/instrumentation/qdrant/qdrant.py +33 -7
- openlit/instrumentation/qdrant/utils.py +228 -93
- openlit/instrumentation/reka/__init__.py +23 -10
- openlit/instrumentation/reka/async_reka.py +17 -11
- openlit/instrumentation/reka/reka.py +17 -11
- openlit/instrumentation/reka/utils.py +138 -36
- openlit/instrumentation/together/__init__.py +44 -12
- openlit/instrumentation/together/async_together.py +50 -27
- openlit/instrumentation/together/together.py +50 -27
- openlit/instrumentation/together/utils.py +301 -71
- openlit/instrumentation/transformers/__init__.py +2 -1
- openlit/instrumentation/transformers/transformers.py +13 -3
- openlit/instrumentation/transformers/utils.py +139 -36
- openlit/instrumentation/vertexai/__init__.py +81 -16
- openlit/instrumentation/vertexai/async_vertexai.py +33 -15
- openlit/instrumentation/vertexai/utils.py +123 -27
- openlit/instrumentation/vertexai/vertexai.py +33 -15
- openlit/instrumentation/vllm/__init__.py +12 -5
- openlit/instrumentation/vllm/utils.py +121 -31
- openlit/instrumentation/vllm/vllm.py +16 -10
- openlit/otel/events.py +35 -10
- openlit/otel/metrics.py +32 -24
- openlit/otel/tracing.py +24 -9
- openlit/semcov/__init__.py +72 -6
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/METADATA +2 -1
- openlit-1.34.31.dist-info/RECORD +166 -0
- openlit/instrumentation/langchain/async_langchain.py +0 -102
- openlit/instrumentation/langchain/langchain.py +0 -102
- openlit/instrumentation/langchain/utils.py +0 -252
- openlit-1.34.30.dist-info/RECORD +0 -168
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/LICENSE +0 -0
- {openlit-1.34.30.dist-info → openlit-1.34.31.dist-info}/WHEEL +0 -0
@@ -4,20 +4,26 @@ Module for monitoring LiteLLM API calls (async version).
|
|
4
4
|
|
5
5
|
import time
|
6
6
|
from opentelemetry.trace import SpanKind
|
7
|
-
from openlit.__helpers import
|
8
|
-
handle_exception,
|
9
|
-
set_server_address_and_port
|
10
|
-
)
|
7
|
+
from openlit.__helpers import handle_exception, set_server_address_and_port
|
11
8
|
from openlit.instrumentation.litellm.utils import (
|
12
9
|
process_chunk,
|
13
10
|
process_streaming_chat_response,
|
14
11
|
process_chat_response,
|
15
|
-
process_embedding_response
|
12
|
+
process_embedding_response,
|
16
13
|
)
|
17
14
|
from openlit.semcov import SemanticConvention
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
|
17
|
+
def acompletion(
|
18
|
+
version,
|
19
|
+
environment,
|
20
|
+
application_name,
|
21
|
+
tracer,
|
22
|
+
pricing_info,
|
23
|
+
capture_message_content,
|
24
|
+
metrics,
|
25
|
+
disable_metrics,
|
26
|
+
):
|
21
27
|
"""
|
22
28
|
Generates a telemetry wrapper for GenAI function call
|
23
29
|
"""
|
@@ -28,15 +34,15 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
28
34
|
"""
|
29
35
|
|
30
36
|
def __init__(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
self,
|
38
|
+
wrapped,
|
39
|
+
span,
|
40
|
+
span_name,
|
41
|
+
kwargs,
|
42
|
+
server_address,
|
43
|
+
server_port,
|
44
|
+
**args,
|
45
|
+
):
|
40
46
|
self.__wrapped__ = wrapped
|
41
47
|
self._span = span
|
42
48
|
self._span_name = span_name
|
@@ -79,7 +85,9 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
79
85
|
return chunk
|
80
86
|
except StopAsyncIteration:
|
81
87
|
try:
|
82
|
-
with tracer.start_as_current_span(
|
88
|
+
with tracer.start_as_current_span(
|
89
|
+
self._span_name, kind=SpanKind.CLIENT
|
90
|
+
) as self._span:
|
83
91
|
process_streaming_chat_response(
|
84
92
|
self,
|
85
93
|
pricing_info=pricing_info,
|
@@ -88,7 +96,7 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
88
96
|
metrics=metrics,
|
89
97
|
capture_message_content=capture_message_content,
|
90
98
|
disable_metrics=disable_metrics,
|
91
|
-
version=version
|
99
|
+
version=version,
|
92
100
|
)
|
93
101
|
|
94
102
|
except Exception as e:
|
@@ -102,7 +110,9 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
102
110
|
"""
|
103
111
|
# Check if streaming is enabled for the API call
|
104
112
|
streaming = kwargs.get("stream", False)
|
105
|
-
server_address, server_port = set_server_address_and_port(
|
113
|
+
server_address, server_port = set_server_address_and_port(
|
114
|
+
instance, "NOT_FOUND", "NOT_FOUND"
|
115
|
+
)
|
106
116
|
request_model = kwargs.get("model", "openai/gpt-4o")
|
107
117
|
|
108
118
|
span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
|
@@ -111,7 +121,9 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
111
121
|
# Special handling for streaming response
|
112
122
|
awaited_wrapped = await wrapped(*args, **kwargs)
|
113
123
|
span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
|
114
|
-
return TracedAsyncStream(
|
124
|
+
return TracedAsyncStream(
|
125
|
+
awaited_wrapped, span, span_name, kwargs, server_address, server_port
|
126
|
+
)
|
115
127
|
else:
|
116
128
|
# Handling for non-streaming responses
|
117
129
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
@@ -133,7 +145,7 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
133
145
|
capture_message_content=capture_message_content,
|
134
146
|
disable_metrics=disable_metrics,
|
135
147
|
version=version,
|
136
|
-
**kwargs
|
148
|
+
**kwargs,
|
137
149
|
)
|
138
150
|
|
139
151
|
except Exception as e:
|
@@ -143,8 +155,17 @@ def acompletion(version, environment, application_name, tracer, pricing_info,
|
|
143
155
|
|
144
156
|
return wrapper
|
145
157
|
|
146
|
-
|
147
|
-
|
158
|
+
|
159
|
+
def aembedding(
|
160
|
+
version,
|
161
|
+
environment,
|
162
|
+
application_name,
|
163
|
+
tracer,
|
164
|
+
pricing_info,
|
165
|
+
capture_message_content,
|
166
|
+
metrics,
|
167
|
+
disable_metrics,
|
168
|
+
):
|
148
169
|
"""
|
149
170
|
Generates a telemetry wrapper for GenAI embedding function call
|
150
171
|
"""
|
@@ -153,10 +174,14 @@ def aembedding(version, environment, application_name, tracer, pricing_info,
|
|
153
174
|
"""
|
154
175
|
Wraps the GenAI embedding function call.
|
155
176
|
"""
|
156
|
-
server_address, server_port = set_server_address_and_port(
|
177
|
+
server_address, server_port = set_server_address_and_port(
|
178
|
+
instance, "NOT_FOUND", "NOT_FOUND"
|
179
|
+
)
|
157
180
|
request_model = kwargs.get("model", "text-embedding-ada-002")
|
158
181
|
|
159
|
-
span_name =
|
182
|
+
span_name = (
|
183
|
+
f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
|
184
|
+
)
|
160
185
|
|
161
186
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
162
187
|
start_time = time.time()
|
@@ -177,7 +202,7 @@ def aembedding(version, environment, application_name, tracer, pricing_info,
|
|
177
202
|
capture_message_content=capture_message_content,
|
178
203
|
disable_metrics=disable_metrics,
|
179
204
|
version=version,
|
180
|
-
**kwargs
|
205
|
+
**kwargs,
|
181
206
|
)
|
182
207
|
|
183
208
|
except Exception as e:
|
@@ -4,20 +4,26 @@ Module for monitoring LiteLLM API calls.
|
|
4
4
|
|
5
5
|
import time
|
6
6
|
from opentelemetry.trace import SpanKind
|
7
|
-
from openlit.__helpers import
|
8
|
-
handle_exception,
|
9
|
-
set_server_address_and_port
|
10
|
-
)
|
7
|
+
from openlit.__helpers import handle_exception, set_server_address_and_port
|
11
8
|
from openlit.instrumentation.litellm.utils import (
|
12
9
|
process_chunk,
|
13
10
|
process_streaming_chat_response,
|
14
11
|
process_chat_response,
|
15
|
-
process_embedding_response
|
12
|
+
process_embedding_response,
|
16
13
|
)
|
17
14
|
from openlit.semcov import SemanticConvention
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
|
17
|
+
def completion(
|
18
|
+
version,
|
19
|
+
environment,
|
20
|
+
application_name,
|
21
|
+
tracer,
|
22
|
+
pricing_info,
|
23
|
+
capture_message_content,
|
24
|
+
metrics,
|
25
|
+
disable_metrics,
|
26
|
+
):
|
21
27
|
"""
|
22
28
|
Generates a telemetry wrapper for GenAI function call
|
23
29
|
"""
|
@@ -28,15 +34,15 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
28
34
|
"""
|
29
35
|
|
30
36
|
def __init__(
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
self,
|
38
|
+
wrapped,
|
39
|
+
span,
|
40
|
+
span_name,
|
41
|
+
kwargs,
|
42
|
+
server_address,
|
43
|
+
server_port,
|
44
|
+
**args,
|
45
|
+
):
|
40
46
|
self.__wrapped__ = wrapped
|
41
47
|
self._span = span
|
42
48
|
self._span_name = span_name
|
@@ -79,7 +85,9 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
79
85
|
return chunk
|
80
86
|
except StopIteration:
|
81
87
|
try:
|
82
|
-
with tracer.start_as_current_span(
|
88
|
+
with tracer.start_as_current_span(
|
89
|
+
self._span_name, kind=SpanKind.CLIENT
|
90
|
+
) as self._span:
|
83
91
|
process_streaming_chat_response(
|
84
92
|
self,
|
85
93
|
pricing_info=pricing_info,
|
@@ -88,7 +96,7 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
88
96
|
metrics=metrics,
|
89
97
|
capture_message_content=capture_message_content,
|
90
98
|
disable_metrics=disable_metrics,
|
91
|
-
version=version
|
99
|
+
version=version,
|
92
100
|
)
|
93
101
|
|
94
102
|
except Exception as e:
|
@@ -102,7 +110,9 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
102
110
|
"""
|
103
111
|
# Check if streaming is enabled for the API call
|
104
112
|
streaming = kwargs.get("stream", False)
|
105
|
-
server_address, server_port = set_server_address_and_port(
|
113
|
+
server_address, server_port = set_server_address_and_port(
|
114
|
+
instance, "NOT_FOUND", "NOT_FOUND"
|
115
|
+
)
|
106
116
|
request_model = kwargs.get("model", "openai/gpt-4o")
|
107
117
|
|
108
118
|
span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
|
@@ -111,7 +121,9 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
111
121
|
# Special handling for streaming response
|
112
122
|
awaited_wrapped = wrapped(*args, **kwargs)
|
113
123
|
span = tracer.start_span(span_name, kind=SpanKind.CLIENT)
|
114
|
-
return TracedSyncStream(
|
124
|
+
return TracedSyncStream(
|
125
|
+
awaited_wrapped, span, span_name, kwargs, server_address, server_port
|
126
|
+
)
|
115
127
|
else:
|
116
128
|
# Handling for non-streaming responses
|
117
129
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
@@ -133,7 +145,7 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
133
145
|
capture_message_content=capture_message_content,
|
134
146
|
disable_metrics=disable_metrics,
|
135
147
|
version=version,
|
136
|
-
**kwargs
|
148
|
+
**kwargs,
|
137
149
|
)
|
138
150
|
|
139
151
|
except Exception as e:
|
@@ -143,8 +155,17 @@ def completion(version, environment, application_name, tracer, pricing_info,
|
|
143
155
|
|
144
156
|
return wrapper
|
145
157
|
|
146
|
-
|
147
|
-
|
158
|
+
|
159
|
+
def embedding(
|
160
|
+
version,
|
161
|
+
environment,
|
162
|
+
application_name,
|
163
|
+
tracer,
|
164
|
+
pricing_info,
|
165
|
+
capture_message_content,
|
166
|
+
metrics,
|
167
|
+
disable_metrics,
|
168
|
+
):
|
148
169
|
"""
|
149
170
|
Generates a telemetry wrapper for GenAI embedding function call
|
150
171
|
"""
|
@@ -153,10 +174,14 @@ def embedding(version, environment, application_name, tracer, pricing_info,
|
|
153
174
|
"""
|
154
175
|
Wraps the GenAI embedding function call.
|
155
176
|
"""
|
156
|
-
server_address, server_port = set_server_address_and_port(
|
177
|
+
server_address, server_port = set_server_address_and_port(
|
178
|
+
instance, "NOT_FOUND", "NOT_FOUND"
|
179
|
+
)
|
157
180
|
request_model = kwargs.get("model", "text-embedding-ada-002")
|
158
181
|
|
159
|
-
span_name =
|
182
|
+
span_name = (
|
183
|
+
f"{SemanticConvention.GEN_AI_OPERATION_TYPE_EMBEDDING} {request_model}"
|
184
|
+
)
|
160
185
|
|
161
186
|
with tracer.start_as_current_span(span_name, kind=SpanKind.CLIENT) as span:
|
162
187
|
start_time = time.time()
|
@@ -177,7 +202,7 @@ def embedding(version, environment, application_name, tracer, pricing_info,
|
|
177
202
|
capture_message_content=capture_message_content,
|
178
203
|
disable_metrics=disable_metrics,
|
179
204
|
version=version,
|
180
|
-
**kwargs
|
205
|
+
**kwargs,
|
181
206
|
)
|
182
207
|
|
183
208
|
except Exception as e:
|