From 9ddc0182cc2be8ccf23ab912fb6d390ca4550ffe Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 11 Aug 2025 18:52:49 +0200 Subject: [PATCH 01/66] init commit --- langfuse/_client/attributes.py | 4 +- langfuse/_client/client.py | 93 ++++++---- langfuse/_client/constants.py | 12 ++ langfuse/_client/observe.py | 272 +++++++++++++++++------------ langfuse/_client/span_processor.py | 2 + langfuse/openai.py | 5 +- 6 files changed, 240 insertions(+), 148 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index 1c22b7518..eef3eb03e 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -93,9 +93,11 @@ def create_span_attributes( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, version: Optional[str] = None, + observation_type: Optional[str] = None, ) -> dict: + final_observation_type = observation_type or "span" attributes = { - LangfuseOtelSpanAttributes.OBSERVATION_TYPE: "span", + LangfuseOtelSpanAttributes.OBSERVATION_TYPE: final_observation_type, LangfuseOtelSpanAttributes.OBSERVATION_LEVEL: level, LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message, LangfuseOtelSpanAttributes.VERSION: version, diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index d205e5d51..106e7d152 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -41,6 +41,11 @@ LangfuseEvent, LangfuseGeneration, LangfuseSpan, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEmbedding, ) from langfuse._utils import _get_timestamp from langfuse._utils.parse_error import handle_fern_exception @@ -345,6 +350,7 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, + observation_type: Optional[str] = None, ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -404,6 +410,7 @@ def start_as_current_span( version=version, level=level, status_message=status_message, + observation_type=observation_type, ), ) @@ -419,6 +426,7 @@ def start_as_current_span( version=version, level=level, status_message=status_message, + observation_type=observation_type, ), ) @@ -661,6 +669,29 @@ def start_as_current_generation( ), ) + def _get_span_class(self, as_type: str, observation_type: Optional[str] = None): + """Get the appropriate span class based on as_type and observation_type.""" + if observation_type == "AGENT": + return LangfuseAgent + elif observation_type == "TOOL": + return LangfuseTool + elif observation_type == "CHAIN": + return LangfuseChain + elif observation_type == "RETRIEVER": + return LangfuseRetriever + elif observation_type == "EMBEDDING": + return LangfuseEmbedding + if as_type == "generation" or observation_type == "GENERATION": + return LangfuseGeneration + elif as_type == "event" or observation_type == "EVENT": + return LangfuseEvent + elif as_type == "span" or observation_type == "SPAN": + return LangfuseSpan + else: + # TODO: this should never happen -> error out? + # for now default to LangfuseSpan for unknown types or "span" as_type + return LangfuseSpan + @_agnosticcontextmanager def _create_span_with_parent_context( self, @@ -682,6 +713,7 @@ def _create_span_with_parent_context( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, + observation_type: Optional[str] = None, ) -> Any: parent_span = parent or cast(otel_trace_api.Span, remote_parent_span) @@ -702,6 +734,7 @@ def _create_span_with_parent_context( usage_details=usage_details, cost_details=cost_details, prompt=prompt, + observation_type=observation_type, ) as langfuse_span: if remote_parent_span is not None: langfuse_span._otel_span.set_attribute( @@ -729,42 +762,42 @@ def _start_as_current_otel_span_with_processed_media( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, + observation_type: Optional[str] = None, ) -> Any: with self._otel_tracer.start_as_current_span( name=name, end_on_exit=end_on_exit if end_on_exit is not None else True, ) as otel_span: - yield ( - LangfuseSpan( - otel_span=otel_span, - langfuse_client=self, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ) - if as_type == "span" - else LangfuseGeneration( - otel_span=otel_span, - langfuse_client=self, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, + span_class = self._get_span_class(as_type, observation_type) + common_args = { + "otel_span": otel_span, + "langfuse_client": self, + "environment": self._environment, + "input": input, + "output": output, + "metadata": metadata, + "version": version, + "level": level, + "status_message": status_message, + } + + if span_class == LangfuseGeneration: + common_args.update( + { + "completion_start_time": completion_start_time, + "model": model, + "model_parameters": model_parameters, + "usage_details": usage_details, + "cost_details": cost_details, + "prompt": prompt, + "observation_type": observation_type, + } ) - ) + else: + if observation_type is not None: + common_args["observation_type"] = observation_type + + yield span_class(**common_args) def _get_current_otel_span(self) -> Optional[otel_trace_api.Span]: current_span = otel_trace_api.get_current_span() diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 1c805ddc3..7ab4e558c 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -4,3 +4,15 @@ """ LANGFUSE_TRACER_NAME = "langfuse-sdk" + +# Valid observation types for the @observe decorator +VALID_OBSERVATION_TYPES = { + "SPAN", + "EVENT", + "GENERATION", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", +} diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 0fef2b5dd..51848af9f 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -19,13 +19,14 @@ overload, ) +from opentelemetry import trace from opentelemetry.util._decorator import _AgnosticContextManager from typing_extensions import ParamSpec +from langfuse._client.attributes import LangfuseOtelSpanAttributes from langfuse._client.environment_variables import ( LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, ) -from langfuse._client.get_client import _set_current_public_key, get_client from langfuse._client.span import LangfuseGeneration, LangfuseSpan from langfuse.types import TraceContext @@ -66,6 +67,7 @@ def observe( *, name: Optional[str] = None, as_type: Optional[Literal["generation"]] = None, + type: Optional[Literal["SPAN", "EVENT", "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -77,6 +79,7 @@ def observe( *, name: Optional[str] = None, as_type: Optional[Literal["generation"]] = None, + type: Optional[Literal["SPAN", "EVENT", "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -95,6 +98,9 @@ def observe( name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used. as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span with model metrics support, suitable for tracking language model outputs. + type (Optional[Literal]): Set the observation type directly. Supported values: "SPAN", "EVENT", + "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING". When specified, creates spans with + the specified type for graph visualization and filtering in the Langfuse UI. Returns: Callable: A wrapped version of the original function that automatically creates and manages Langfuse spans. @@ -120,6 +126,20 @@ async def generate_answer(query): return response.choices[0].message.content ``` + For automatic graph instrumentation with agent workflows: + ```python + @observe(type="AGENT") + def planning_agent(): + # Creates a span with observation type "AGENT" for graph visualization + return create_plan() + + @observe(type="AGENT") + def execution_agent(): + # Creates a span with observation type "AGENT" + # Parent relationships inferred from OpenTelemetry span hierarchy + return execute_plan() + ``` + For trace context propagation between functions: ```python @observe() @@ -146,6 +166,14 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ + # Validate type parameter if provided + if type is not None: + from langfuse._client.constants import VALID_OBSERVATION_TYPES + if type not in VALID_OBSERVATION_TYPES: + raise ValueError( + f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" + ) + function_io_capture_enabled = os.environ.get( LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, "True" ).lower() not in ("false", "0") @@ -166,6 +194,7 @@ def decorator(func: F) -> F: func, name=name, as_type=as_type, + observation_type=type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -175,6 +204,7 @@ def decorator(func: F) -> F: func, name=name, as_type=as_type, + observation_type=type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -188,7 +218,7 @@ def decorator(func: F) -> F: - @observe() - Python calls the decorator first, which must return a function decorator When called without arguments (@observe), the func parameter contains the function to decorate, - so we directly apply the decorator to it. When called with parentheses (@observe()), + so we directly apply the decorator to it. When called with parentheses (@observe()), func is None, so we return the decorator function itself for Python to apply in the next step. """ if func is None: @@ -202,6 +232,7 @@ def _async_observe( *, name: Optional[str], as_type: Optional[Literal["generation"]], + observation_type: Optional[str], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -221,6 +252,7 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: else None ) final_name = name or func.__name__ + input = ( self._get_input_from_func_args( is_method=self._is_method(func), @@ -231,75 +263,78 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: else None ) public_key = cast(str, kwargs.pop("langfuse_public_key", None)) - - # Set public key in execution context for nested decorated functions - with _set_current_public_key(public_key): - langfuse_client = get_client(public_key=public_key) - context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - ] - ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if as_type == "generation" - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) + langfuse_client = get_client(public_key=public_key) + + # Determine final observation type and create appropriate span + final_obs_type = observation_type or as_type + + context_manager: Optional[ + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + ] + ] = ( + ( + langfuse_client.start_as_current_generation( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + ) + if final_obs_type == "generation" or observation_type == "GENERATION" + else langfuse_client.start_as_current_span( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + observation_type=observation_type, ) - if langfuse_client - else None ) + if langfuse_client + else None + ) - if context_manager is None: - return await func(*args, **kwargs) + if context_manager is None: + return await func(*args, **kwargs) - with context_manager as langfuse_span_or_generation: - is_return_type_generator = False + with context_manager as langfuse_span_or_generation: + + is_return_type_generator = False - try: - result = await func(*args, **kwargs) + try: + result = await func(*args, **kwargs) - if capture_output is True: - if inspect.isgenerator(result): - is_return_type_generator = True + if capture_output is True: + if inspect.isgenerator(result): + is_return_type_generator = True - return self._wrap_sync_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_sync_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - if inspect.isasyncgen(result): - is_return_type_generator = True + if inspect.isasyncgen(result): + is_return_type_generator = True - return self._wrap_async_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_async_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - langfuse_span_or_generation.update(output=result) + langfuse_span_or_generation.update(output=result) - return result - except Exception as e: - langfuse_span_or_generation.update( - level="ERROR", status_message=str(e) - ) + return result + except Exception as e: + langfuse_span_or_generation.update( + level="ERROR", status_message=str(e) + ) - raise e - finally: - if not is_return_type_generator: - langfuse_span_or_generation.end() + raise e + finally: + if not is_return_type_generator: + langfuse_span_or_generation.end() return cast(F, async_wrapper) @@ -309,6 +344,7 @@ def _sync_observe( *, name: Optional[str], as_type: Optional[Literal["generation"]], + observation_type: Optional[str], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -326,6 +362,7 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: else None ) final_name = name or func.__name__ + input = ( self._get_input_from_func_args( is_method=self._is_method(func), @@ -336,75 +373,77 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: else None ) public_key = kwargs.pop("langfuse_public_key", None) - - # Set public key in execution context for nested decorated functions - with _set_current_public_key(public_key): - langfuse_client = get_client(public_key=public_key) - context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - ] - ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if as_type == "generation" - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) + langfuse_client = get_client(public_key=public_key) + + # Determine final observation type and create appropriate span + final_obs_type = observation_type or as_type + + context_manager: Optional[ + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + ] + ] = ( + ( + langfuse_client.start_as_current_generation( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + ) + if final_obs_type == "generation" or observation_type == "GENERATION" + else langfuse_client.start_as_current_span( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + observation_type=observation_type, ) - if langfuse_client - else None ) + if langfuse_client + else None + ) - if context_manager is None: - return func(*args, **kwargs) + if context_manager is None: + return func(*args, **kwargs) - with context_manager as langfuse_span_or_generation: - is_return_type_generator = False + with context_manager as langfuse_span_or_generation: + is_return_type_generator = False - try: - result = func(*args, **kwargs) + try: + result = func(*args, **kwargs) - if capture_output is True: - if inspect.isgenerator(result): - is_return_type_generator = True + if capture_output is True: + if inspect.isgenerator(result): + is_return_type_generator = True - return self._wrap_sync_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_sync_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - if inspect.isasyncgen(result): - is_return_type_generator = True + if inspect.isasyncgen(result): + is_return_type_generator = True - return self._wrap_async_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_async_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - langfuse_span_or_generation.update(output=result) + langfuse_span_or_generation.update(output=result) - return result - except Exception as e: - langfuse_span_or_generation.update( - level="ERROR", status_message=str(e) - ) + return result + except Exception as e: + langfuse_span_or_generation.update( + level="ERROR", status_message=str(e) + ) - raise e - finally: - if not is_return_type_generator: - langfuse_span_or_generation.end() + raise e + finally: + if not is_return_type_generator: + langfuse_span_or_generation.end() return cast(F, sync_wrapper) @@ -415,6 +454,7 @@ def _is_method(func: Callable) -> bool: or "cls" in inspect.signature(func).parameters ) + def _get_input_from_func_args( self, *, diff --git a/langfuse/_client/span_processor.py b/langfuse/_client/span_processor.py index ca8fb9b5a..233eae0cd 100644 --- a/langfuse/_client/span_processor.py +++ b/langfuse/_client/span_processor.py @@ -12,6 +12,7 @@ """ import base64 +import json import os from typing import Dict, List, Optional @@ -152,3 +153,4 @@ def _is_langfuse_project_span(self, span: ReadableSpan) -> bool: return public_key_on_span == self.public_key return False + diff --git a/langfuse/openai.py b/langfuse/openai.py index b8d9ea2d7..ac711e2de 100644 --- a/langfuse/openai.py +++ b/langfuse/openai.py @@ -570,7 +570,10 @@ def _extract_streamed_openai_response(resource: Any, chunks: Any) -> Any: ) curr["arguments"] += getattr(tool_call_chunk, "arguments", "") - elif delta.get("tool_calls", None) is not None and len(delta.get("tool_calls")) > 0: + elif ( + delta.get("tool_calls", None) is not None + and len(delta.get("tool_calls")) > 0 + ): curr = completion["tool_calls"] tool_call_chunk = getattr( delta.get("tool_calls", None)[0], "function", None From 1bc90b038f5aab52da8443f69c0491df211de707 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 09:56:59 +0200 Subject: [PATCH 02/66] Use as_type --- langfuse/_client/client.py | 53 +++++---- langfuse/_client/observe.py | 101 +++++++++------- langfuse/_client/span.py | 178 +++++++++++++++++++++++++++-- langfuse/_client/span_processor.py | 2 - 4 files changed, 257 insertions(+), 77 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 106e7d152..36f1f7427 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -350,7 +350,7 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - observation_type: Optional[str] = None, + as_type: Optional[str] = None, ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -410,14 +410,13 @@ def start_as_current_span( version=version, level=level, status_message=status_message, - observation_type=observation_type, ), ) return cast( _AgnosticContextManager[LangfuseSpan], self._start_as_current_otel_span_with_processed_media( - as_type="span", + as_type=as_type, name=name, end_on_exit=end_on_exit, input=input, @@ -426,7 +425,6 @@ def start_as_current_span( version=version, level=level, status_message=status_message, - observation_type=observation_type, ), ) @@ -669,27 +667,26 @@ def start_as_current_generation( ), ) - def _get_span_class(self, as_type: str, observation_type: Optional[str] = None): - """Get the appropriate span class based on as_type and observation_type.""" - if observation_type == "AGENT": + def _get_span_class(self, as_type: str): + """Get the appropriate span class based on as_type.""" + if as_type == "AGENT": return LangfuseAgent - elif observation_type == "TOOL": + elif as_type == "TOOL": return LangfuseTool - elif observation_type == "CHAIN": + elif as_type == "CHAIN": return LangfuseChain - elif observation_type == "RETRIEVER": + elif as_type == "RETRIEVER": return LangfuseRetriever - elif observation_type == "EMBEDDING": + elif as_type == "EMBEDDING": return LangfuseEmbedding - if as_type == "generation" or observation_type == "GENERATION": + elif as_type in ("generation", "GENERATION"): return LangfuseGeneration - elif as_type == "event" or observation_type == "EVENT": + elif as_type in ("event", "EVENT"): return LangfuseEvent - elif as_type == "span" or observation_type == "SPAN": + elif as_type in ("span", "SPAN"): return LangfuseSpan else: - # TODO: this should never happen -> error out? - # for now default to LangfuseSpan for unknown types or "span" as_type + # Default to LangfuseSpan for unknown types return LangfuseSpan @_agnosticcontextmanager @@ -699,7 +696,7 @@ def _create_span_with_parent_context( name: str, parent: Optional[otel_trace_api.Span] = None, remote_parent_span: Optional[otel_trace_api.Span] = None, - as_type: Literal["generation", "span"], + as_type: Optional[str] = None, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -713,7 +710,6 @@ def _create_span_with_parent_context( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - observation_type: Optional[str] = None, ) -> Any: parent_span = parent or cast(otel_trace_api.Span, remote_parent_span) @@ -734,7 +730,6 @@ def _create_span_with_parent_context( usage_details=usage_details, cost_details=cost_details, prompt=prompt, - observation_type=observation_type, ) as langfuse_span: if remote_parent_span is not None: langfuse_span._otel_span.set_attribute( @@ -748,7 +743,7 @@ def _start_as_current_otel_span_with_processed_media( self, *, name: str, - as_type: Optional[Literal["generation", "span"]] = None, + as_type: Optional[str] = None, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -762,13 +757,12 @@ def _start_as_current_otel_span_with_processed_media( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - observation_type: Optional[str] = None, ) -> Any: with self._otel_tracer.start_as_current_span( name=name, end_on_exit=end_on_exit if end_on_exit is not None else True, ) as otel_span: - span_class = self._get_span_class(as_type, observation_type) + span_class = self._get_span_class(as_type) common_args = { "otel_span": otel_span, "langfuse_client": self, @@ -790,12 +784,21 @@ def _start_as_current_otel_span_with_processed_media( "usage_details": usage_details, "cost_details": cost_details, "prompt": prompt, - "observation_type": observation_type, } ) + elif span_class in [ + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEmbedding, + ]: + # Graph observation classes set their specific observation_type internally + pass else: - if observation_type is not None: - common_args["observation_type"] = observation_type + # Regular spans (LangfuseSpan, LangfuseEvent) need as_type + if as_type is not None: + common_args["as_type"] = as_type yield span_class(**common_args) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 51848af9f..6c6400fda 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -19,14 +19,15 @@ overload, ) -from opentelemetry import trace from opentelemetry.util._decorator import _AgnosticContextManager from typing_extensions import ParamSpec -from langfuse._client.attributes import LangfuseOtelSpanAttributes from langfuse._client.environment_variables import ( LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, ) + +from langfuse._client.constants import VALID_OBSERVATION_TYPES +from langfuse._client.get_client import _set_current_public_key, get_client from langfuse._client.span import LangfuseGeneration, LangfuseSpan from langfuse.types import TraceContext @@ -67,7 +68,18 @@ def observe( *, name: Optional[str] = None, as_type: Optional[Literal["generation"]] = None, - type: Optional[Literal["SPAN", "EVENT", "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]] = None, + type: Optional[ + Literal[ + "SPAN", + "EVENT", + "GENERATION", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", + ] + ] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -79,7 +91,18 @@ def observe( *, name: Optional[str] = None, as_type: Optional[Literal["generation"]] = None, - type: Optional[Literal["SPAN", "EVENT", "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]] = None, + type: Optional[ + Literal[ + "SPAN", + "EVENT", + "GENERATION", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", + ] + ] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -98,8 +121,8 @@ def observe( name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used. as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span with model metrics support, suitable for tracking language model outputs. - type (Optional[Literal]): Set the observation type directly. Supported values: "SPAN", "EVENT", - "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING". When specified, creates spans with + type (Optional[Literal]): Set the observation type for agentic workflows. Supported values: "SPAN", "EVENT", + "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING". When specified, creates spans with the specified type for graph visualization and filtering in the Langfuse UI. Returns: @@ -130,14 +153,7 @@ async def generate_answer(query): ```python @observe(type="AGENT") def planning_agent(): - # Creates a span with observation type "AGENT" for graph visualization return create_plan() - - @observe(type="AGENT") - def execution_agent(): - # Creates a span with observation type "AGENT" - # Parent relationships inferred from OpenTelemetry span hierarchy - return execute_plan() ``` For trace context propagation between functions: @@ -166,13 +182,19 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ - # Validate type parameter if provided - if type is not None: - from langfuse._client.constants import VALID_OBSERVATION_TYPES - if type not in VALID_OBSERVATION_TYPES: - raise ValueError( - f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" - ) + # Validate parameters + if type is not None and type not in VALID_OBSERVATION_TYPES: + raise ValueError( + f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" + ) + if as_type is not None and as_type.upper() not in VALID_OBSERVATION_TYPES: + valid_values = sorted( + list(VALID_OBSERVATION_TYPES) + + [t.lower() for t in VALID_OBSERVATION_TYPES] + ) + raise ValueError( + f"Invalid as_type '{as_type}'. Valid values are: {', '.join(valid_values)}" + ) function_io_capture_enabled = os.environ.get( LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, "True" @@ -189,12 +211,14 @@ def sub_process(): ) def decorator(func: F) -> F: + # Merge as_type and type parameters - type takes precedence for graph observations + final_as_type = type or as_type + return ( self._async_observe( func, name=name, - as_type=as_type, - observation_type=type, + as_type=final_as_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -203,8 +227,7 @@ def decorator(func: F) -> F: else self._sync_observe( func, name=name, - as_type=as_type, - observation_type=type, + as_type=final_as_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -231,8 +254,7 @@ def _async_observe( func: F, *, name: Optional[str], - as_type: Optional[Literal["generation"]], - observation_type: Optional[str], + as_type: Optional[str], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -252,7 +274,6 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: else None ) final_name = name or func.__name__ - input = ( self._get_input_from_func_args( is_method=self._is_method(func), @@ -264,9 +285,9 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: ) public_key = cast(str, kwargs.pop("langfuse_public_key", None)) langfuse_client = get_client(public_key=public_key) - - # Determine final observation type and create appropriate span - final_obs_type = observation_type or as_type + + # Use consolidated as_type parameter + final_obs_type = as_type context_manager: Optional[ Union[ @@ -281,13 +302,13 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early ) - if final_obs_type == "generation" or observation_type == "GENERATION" + if final_obs_type in ("generation", "GENERATION") else langfuse_client.start_as_current_span( name=final_name, trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early - observation_type=observation_type, + as_type=final_obs_type, ) ) if langfuse_client @@ -298,7 +319,6 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: return await func(*args, **kwargs) with context_manager as langfuse_span_or_generation: - is_return_type_generator = False try: @@ -343,8 +363,7 @@ def _sync_observe( func: F, *, name: Optional[str], - as_type: Optional[Literal["generation"]], - observation_type: Optional[str], + as_type: Optional[str], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -362,7 +381,6 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: else None ) final_name = name or func.__name__ - input = ( self._get_input_from_func_args( is_method=self._is_method(func), @@ -374,9 +392,9 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: ) public_key = kwargs.pop("langfuse_public_key", None) langfuse_client = get_client(public_key=public_key) - - # Determine final observation type and create appropriate span - final_obs_type = observation_type or as_type + + # Use consolidated as_type parameter + final_obs_type = as_type context_manager: Optional[ Union[ @@ -391,13 +409,13 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early ) - if final_obs_type == "generation" or observation_type == "GENERATION" + if final_obs_type in ("generation", "GENERATION") else langfuse_client.start_as_current_span( name=final_name, trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early - observation_type=observation_type, + as_type=final_obs_type, ) ) if langfuse_client @@ -454,7 +472,6 @@ def _is_method(func: Callable) -> bool: or "cls" in inspect.signature(func).parameters ) - def _get_input_from_func_args( self, *, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 34aa4f0d1..5d90a8654 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -64,7 +64,7 @@ def __init__( *, otel_span: otel_trace_api.Span, langfuse_client: "Langfuse", - as_type: Literal["span", "generation", "event"], + as_type: Literal["span", "generation", "event", "agent", "tool", "chain", "retriever", "embedding"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -100,9 +100,6 @@ def __init__( prompt: Associated prompt template from Langfuse prompt management """ self._otel_span = otel_span - self._otel_span.set_attribute( - LangfuseOtelSpanAttributes.OBSERVATION_TYPE, as_type - ) self._langfuse_client = langfuse_client self.trace_id = self._langfuse_client._get_otel_trace_id(otel_span) @@ -152,12 +149,19 @@ def __init__( version=version, level=level, status_message=status_message, + observation_type=as_type, ) - attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) + # Keep OBSERVATION_TYPE in attributes - don't remove it + # attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) + + final_attributes = {k: v for k, v in attributes.items() if v is not None} + self._otel_span.set_attributes(final_attributes) - self._otel_span.set_attributes( - {k: v for k, v in attributes.items() if v is not None} + # Check what actually got set + actual_attributes = dict(self._otel_span.attributes) + obs_type_value = actual_attributes.get( + "langfuse.observation.type", "NOT_FOUND" ) def end(self, *, end_time: Optional[int] = None) -> "LangfuseSpanWrapper": @@ -533,6 +537,7 @@ def __init__( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, + as_type: Optional[Literal["span", "generation", "event", "agent", "tool", "chain", "retriever", "embedding"]] = None, ): """Initialize a new LangfuseSpan. @@ -547,9 +552,11 @@ def __init__( level: Importance level of the span (info, warning, error) status_message: Optional status message for the span """ + # Default to span if not provided mimicing previous behavior + final_as_type = as_type or "span" super().__init__( otel_span=otel_span, - as_type="span", + as_type=final_as_type, langfuse_client=langfuse_client, input=input, output=output, @@ -1199,3 +1206,158 @@ def __init__( level=level, status_message=status_message, ) + + +class LangfuseGraphObservation(LangfuseSpanWrapper): + """Base class for agentic workflow observations. + + This class provides a common foundation for specialized observation types + used in agentic workflows: AGENT, TOOL, CHAIN, RETRIEVER, and EMBEDDING. + All graph observations use span-type attributes but with specific observation types. + """ + + def __init__( + self, + *, + observation_type: str, + otel_span: otel_trace_api.Span, + langfuse_client: "Langfuse", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + environment: Optional[str] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ): + """Initialize a new graph observation span. + + Args: + observation_type: The specific observation type (e.g., "AGENT", "TOOL") + otel_span: The OpenTelemetry span to wrap + langfuse_client: Reference to the parent Langfuse client + input: Input data for the observation + output: Output data from the observation + metadata: Additional metadata to associate with the observation + environment: The tracing environment + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + """ + super().__init__( + otel_span=otel_span, + as_type="span", # Use span-type attributes for all graph observations + langfuse_client=langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=environment, + version=version, + level=level, + status_message=status_message, + ) + + # Store the observation type for use in update method + self._observation_type = observation_type + + def update( + self, + *, + name: Optional[str] = None, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + **kwargs: Any, + ) -> "LangfuseGraphObservation": + """Update this graph observation with new information. + + This method updates the observation with new information that becomes available + during execution, such as outputs, metadata, or status changes. + + Args: + name: Observation name + input: Updated input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + **kwargs: Additional keyword arguments (ignored) + """ + if not self._otel_span.is_recording(): + return self + + processed_input = self._process_media_and_apply_mask( + data=input, field="input", span=self._otel_span + ) + processed_output = self._process_media_and_apply_mask( + data=output, field="output", span=self._otel_span + ) + processed_metadata = self._process_media_and_apply_mask( + data=metadata, field="metadata", span=self._otel_span + ) + + if name: + self._otel_span.update_name(name) + + attributes = create_span_attributes( + input=processed_input, + output=processed_output, + metadata=processed_metadata, + version=version, + level=level, + status_message=status_message, + observation_type=self._observation_type, + ) + + self._otel_span.set_attributes(attributes=attributes) + + return self + + +class LangfuseAgent(LangfuseGraphObservation): + """Specialized span for AGENT observations in agentic workflows.""" + + def __init__(self, **kwargs): + """Initialize a new LangfuseAgent span.""" + kwargs["observation_type"] = "AGENT" + super().__init__(**kwargs) + + +class LangfuseTool(LangfuseGraphObservation): + """Specialized span for TOOL observations in agentic workflows.""" + + def __init__(self, **kwargs): + """Initialize a new LangfuseTool span.""" + kwargs["observation_type"] = "TOOL" + super().__init__(**kwargs) + + +class LangfuseChain(LangfuseGraphObservation): + """Specialized span for CHAIN observations in agentic workflows.""" + + def __init__(self, **kwargs): + """Initialize a new LangfuseChain span.""" + kwargs["observation_type"] = "CHAIN" + super().__init__(**kwargs) + + +class LangfuseRetriever(LangfuseGraphObservation): + """Specialized span for RETRIEVER observations in agentic workflows.""" + + def __init__(self, **kwargs): + """Initialize a new LangfuseRetriever span.""" + kwargs["observation_type"] = "RETRIEVER" + super().__init__(**kwargs) + + +class LangfuseEmbedding(LangfuseGraphObservation): + """Specialized span for EMBEDDING observations in agentic workflows.""" + + def __init__(self, **kwargs): + """Initialize a new LangfuseEmbedding span.""" + kwargs["observation_type"] = "EMBEDDING" + super().__init__(**kwargs) diff --git a/langfuse/_client/span_processor.py b/langfuse/_client/span_processor.py index 233eae0cd..ca8fb9b5a 100644 --- a/langfuse/_client/span_processor.py +++ b/langfuse/_client/span_processor.py @@ -12,7 +12,6 @@ """ import base64 -import json import os from typing import Dict, List, Optional @@ -153,4 +152,3 @@ def _is_langfuse_project_span(self, span: ReadableSpan) -> bool: return public_key_on_span == self.public_key return False - From 7f717892dcd91cdc164ad193963eba5014815fb4 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 10:51:33 +0200 Subject: [PATCH 03/66] clean --- langfuse/_client/client.py | 7 +++---- langfuse/_client/observe.py | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 36f1f7427..768b311c1 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -669,6 +669,7 @@ def start_as_current_generation( def _get_span_class(self, as_type: str): """Get the appropriate span class based on as_type.""" + # TODO: make it case insensitive if as_type == "AGENT": return LangfuseAgent elif as_type == "TOOL": @@ -686,7 +687,6 @@ def _get_span_class(self, as_type: str): elif as_type in ("span", "SPAN"): return LangfuseSpan else: - # Default to LangfuseSpan for unknown types return LangfuseSpan @_agnosticcontextmanager @@ -696,7 +696,7 @@ def _create_span_with_parent_context( name: str, parent: Optional[otel_trace_api.Span] = None, remote_parent_span: Optional[otel_trace_api.Span] = None, - as_type: Optional[str] = None, + as_type: Literal["generation", "span", "AGENT", "TOOL", "CHAIN", "RETRIEVER"], end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -793,10 +793,9 @@ def _start_as_current_otel_span_with_processed_media( LangfuseRetriever, LangfuseEmbedding, ]: - # Graph observation classes set their specific observation_type internally + # set their type internally in the class pass else: - # Regular spans (LangfuseSpan, LangfuseEvent) need as_type if as_type is not None: common_args["as_type"] = as_type diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 6c6400fda..c375d10de 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -121,7 +121,7 @@ def observe( name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used. as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span with model metrics support, suitable for tracking language model outputs. - type (Optional[Literal]): Set the observation type for agentic workflows. Supported values: "SPAN", "EVENT", + type (Optional[Literal]): Set the observation type for agentic workflows. Supported values: "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING". When specified, creates spans with the specified type for graph visualization and filtering in the Langfuse UI. @@ -182,7 +182,6 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ - # Validate parameters if type is not None and type not in VALID_OBSERVATION_TYPES: raise ValueError( f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" @@ -235,11 +234,11 @@ def decorator(func: F) -> F: ) """Handle decorator with or without parentheses. - + This logic enables the decorator to work both with and without parentheses: - @observe - Python passes the function directly to the decorator - @observe() - Python calls the decorator first, which must return a function decorator - + When called without arguments (@observe), the func parameter contains the function to decorate, so we directly apply the decorator to it. When called with parentheses (@observe()), func is None, so we return the decorator function itself for Python to apply in the next step. From df8ff8e982e73275c763a894beed72666fd3b592 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 11:20:13 +0200 Subject: [PATCH 04/66] cleanup --- langfuse/_client/client.py | 2 +- langfuse/_client/span.py | 16 ++++------------ langfuse/openai.py | 5 +---- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 768b311c1..116c45677 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -667,7 +667,7 @@ def start_as_current_generation( ), ) - def _get_span_class(self, as_type: str): + def _get_span_class(self, as_type: Literal["span", "generation", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]): """Get the appropriate span class based on as_type.""" # TODO: make it case insensitive if as_type == "AGENT": diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 5d90a8654..b774a6491 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -152,16 +152,10 @@ def __init__( observation_type=as_type, ) - # Keep OBSERVATION_TYPE in attributes - don't remove it - # attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) + attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) - final_attributes = {k: v for k, v in attributes.items() if v is not None} - self._otel_span.set_attributes(final_attributes) - - # Check what actually got set - actual_attributes = dict(self._otel_span.attributes) - obs_type_value = actual_attributes.get( - "langfuse.observation.type", "NOT_FOUND" + self._otel_span.set_attributes( + {k: v for k, v in attributes.items() if v is not None} ) def end(self, *, end_time: Optional[int] = None) -> "LangfuseSpanWrapper": @@ -552,11 +546,9 @@ def __init__( level: Importance level of the span (info, warning, error) status_message: Optional status message for the span """ - # Default to span if not provided mimicing previous behavior - final_as_type = as_type or "span" super().__init__( otel_span=otel_span, - as_type=final_as_type, + as_type="span", langfuse_client=langfuse_client, input=input, output=output, diff --git a/langfuse/openai.py b/langfuse/openai.py index ac711e2de..b8d9ea2d7 100644 --- a/langfuse/openai.py +++ b/langfuse/openai.py @@ -570,10 +570,7 @@ def _extract_streamed_openai_response(resource: Any, chunks: Any) -> Any: ) curr["arguments"] += getattr(tool_call_chunk, "arguments", "") - elif ( - delta.get("tool_calls", None) is not None - and len(delta.get("tool_calls")) > 0 - ): + elif delta.get("tool_calls", None) is not None and len(delta.get("tool_calls")) > 0: curr = completion["tool_calls"] tool_call_chunk = getattr( delta.get("tool_calls", None)[0], "function", None From c3be3d8d7b3621e82678a6d0d4271e91277265c4 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 11:41:49 +0200 Subject: [PATCH 05/66] cleanup --- langfuse/_client/attributes.py | 3 +-- langfuse/_client/client.py | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index eef3eb03e..8c3beccfe 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -95,9 +95,8 @@ def create_span_attributes( version: Optional[str] = None, observation_type: Optional[str] = None, ) -> dict: - final_observation_type = observation_type or "span" attributes = { - LangfuseOtelSpanAttributes.OBSERVATION_TYPE: final_observation_type, + LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type or "span", LangfuseOtelSpanAttributes.OBSERVATION_LEVEL: level, LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message, LangfuseOtelSpanAttributes.VERSION: version, diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 116c45677..4c08c870e 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -350,7 +350,7 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - as_type: Optional[str] = None, + as_type: Optional[Literal["generation", "span", "event", "agent", "tool", "chain", "retriever"]] = None, ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -743,7 +743,7 @@ def _start_as_current_otel_span_with_processed_media( self, *, name: str, - as_type: Optional[str] = None, + as_type: Optional[Literal["generation", "span", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER"]] = None, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -762,7 +762,7 @@ def _start_as_current_otel_span_with_processed_media( name=name, end_on_exit=end_on_exit if end_on_exit is not None else True, ) as otel_span: - span_class = self._get_span_class(as_type) + span_class = self._get_span_class(as_type or "generation") common_args = { "otel_span": otel_span, "langfuse_client": self, From 2f34092ba87c68c4c06435bcd091e77e085fc8e1 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 12:13:29 +0200 Subject: [PATCH 06/66] todo clarifty case sensitivity --- langfuse/_client/client.py | 2 +- langfuse/_client/observe.py | 133 +++++++++++++++++++----------------- 2 files changed, 71 insertions(+), 64 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 121770473..ecf925c7a 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -355,7 +355,7 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - as_type: Optional[Literal["generation", "span", "event", "agent", "tool", "chain", "retriever"]] = None, + as_type: Optional[Literal["generation", "span", "GENERATION", "EVENT", "SPAN", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]], ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index c375d10de..2e3915d0c 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -182,6 +182,10 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ + if as_type is not None and type is not None: + raise ValueError( + "Cannot specify both 'as_type' and 'type' parameters. Please use only one of them." + ) if type is not None and type not in VALID_OBSERVATION_TYPES: raise ValueError( f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" @@ -210,14 +214,14 @@ def sub_process(): ) def decorator(func: F) -> F: - # Merge as_type and type parameters - type takes precedence for graph observations - final_as_type = type or as_type + # TODO: merge smartly with manually set as_type + consolidated_type = type or as_type return ( self._async_observe( func, name=name, - as_type=final_as_type, + as_type=consolidated_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -226,7 +230,7 @@ def decorator(func: F) -> F: else self._sync_observe( func, name=name, - as_type=final_as_type, + as_type=consolidated_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -253,7 +257,7 @@ def _async_observe( func: F, *, name: Optional[str], - as_type: Optional[str], + as_type: Optional[Literal["generation", "GENERATION", "EVENT", "SPAN", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -283,77 +287,80 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: else None ) public_key = cast(str, kwargs.pop("langfuse_public_key", None)) - langfuse_client = get_client(public_key=public_key) - # Use consolidated as_type parameter - final_obs_type = as_type - - context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - ] - ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if final_obs_type in ("generation", "GENERATION") - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=final_obs_type, + # Set public key in execution context for nested decorated functions + with _set_current_public_key(public_key): + langfuse_client = get_client(public_key=public_key) + + # Use consolidated as_type parameter + final_obs_type = as_type + + context_manager: Optional[ + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + ] + ] = ( + ( + langfuse_client.start_as_current_generation( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + ) + if final_obs_type in ("generation", "GENERATION") + else langfuse_client.start_as_current_span( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + as_type=final_obs_type, + ) ) + if langfuse_client + else None ) - if langfuse_client - else None - ) - if context_manager is None: - return await func(*args, **kwargs) + if context_manager is None: + return await func(*args, **kwargs) - with context_manager as langfuse_span_or_generation: - is_return_type_generator = False + with context_manager as langfuse_span_or_generation: + is_return_type_generator = False - try: - result = await func(*args, **kwargs) + try: + result = await func(*args, **kwargs) - if capture_output is True: - if inspect.isgenerator(result): - is_return_type_generator = True + if capture_output is True: + if inspect.isgenerator(result): + is_return_type_generator = True - return self._wrap_sync_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_sync_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - if inspect.isasyncgen(result): - is_return_type_generator = True + if inspect.isasyncgen(result): + is_return_type_generator = True - return self._wrap_async_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_async_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - langfuse_span_or_generation.update(output=result) + langfuse_span_or_generation.update(output=result) - return result - except Exception as e: - langfuse_span_or_generation.update( - level="ERROR", status_message=str(e) - ) + return result + except Exception as e: + langfuse_span_or_generation.update( + level="ERROR", status_message=str(e) + ) - raise e - finally: - if not is_return_type_generator: - langfuse_span_or_generation.end() + raise e + finally: + if not is_return_type_generator: + langfuse_span_or_generation.end() return cast(F, async_wrapper) From 6b36bd17866b98b26da1c8dc9f9c88890cda5f28 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 12:13:58 +0200 Subject: [PATCH 07/66] format --- langfuse/_client/client.py | 37 +++++++++++++++++++++++++++++++++---- langfuse/_client/observe.py | 14 +++++++++++++- langfuse/_client/span.py | 24 ++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index ecf925c7a..ce7d2521c 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -355,7 +355,20 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - as_type: Optional[Literal["generation", "span", "GENERATION", "EVENT", "SPAN", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]], + as_type: Optional[ + Literal[ + "generation", + "span", + "GENERATION", + "EVENT", + "SPAN", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", + ] + ], ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -672,7 +685,19 @@ def start_as_current_generation( ), ) - def _get_span_class(self, as_type: Literal["span", "generation", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]): + def _get_span_class( + self, + as_type: Literal[ + "span", + "generation", + "event", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", + ], + ): """Get the appropriate span class based on as_type.""" # TODO: make it case insensitive if as_type == "AGENT": @@ -701,7 +726,7 @@ def _create_span_with_parent_context( name: str, parent: Optional[otel_trace_api.Span] = None, remote_parent_span: Optional[otel_trace_api.Span] = None, - as_type: Literal["generation", "span", "AGENT", "TOOL", "CHAIN", "RETRIEVER"], + as_type: Literal["generation", "span", "agent", "tool", "chain", "retriever"], end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -748,7 +773,11 @@ def _start_as_current_otel_span_with_processed_media( self, *, name: str, - as_type: Optional[Literal["generation", "span", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER"]] = None, + as_type: Optional[ + Literal[ + "generation", "span", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER" + ] + ] = None, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 2e3915d0c..2136ba3ef 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -257,7 +257,19 @@ def _async_observe( func: F, *, name: Optional[str], - as_type: Optional[Literal["generation", "GENERATION", "EVENT", "SPAN", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING"]], + as_type: Optional[ + Literal[ + "generation", + "GENERATION", + "EVENT", + "SPAN", + "AGENT", + "TOOL", + "CHAIN", + "RETRIEVER", + "EMBEDDING", + ] + ], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index b774a6491..fcfa681c9 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -64,7 +64,16 @@ def __init__( *, otel_span: otel_trace_api.Span, langfuse_client: "Langfuse", - as_type: Literal["span", "generation", "event", "agent", "tool", "chain", "retriever", "embedding"], + as_type: Literal[ + "span", + "generation", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", + ], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -531,7 +540,18 @@ def __init__( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - as_type: Optional[Literal["span", "generation", "event", "agent", "tool", "chain", "retriever", "embedding"]] = None, + as_type: Optional[ + Literal[ + "span", + "generation", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", + ] + ] = None, ): """Initialize a new LangfuseSpan. From 6e0695b3d8ec9718444d3b3b976060b9e6ae758e Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 12:16:55 +0200 Subject: [PATCH 08/66] revert --- langfuse/_client/observe.py | 121 ++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 2136ba3ef..8f25c8207 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -409,77 +409,80 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: else None ) public_key = kwargs.pop("langfuse_public_key", None) - langfuse_client = get_client(public_key=public_key) - - # Use consolidated as_type parameter - final_obs_type = as_type - - context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - ] - ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if final_obs_type in ("generation", "GENERATION") - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=final_obs_type, + + # Set public key in execution context for nested decorated functions + with _set_current_public_key(public_key): + langfuse_client = get_client(public_key=public_key) + + # Use consolidated as_type parameter + final_obs_type = as_type + + context_manager: Optional[ + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + ] + ] = ( + ( + langfuse_client.start_as_current_generation( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + ) + if final_obs_type in ("generation", "GENERATION") + else langfuse_client.start_as_current_span( + name=final_name, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early + as_type=final_obs_type, + ) ) + if langfuse_client + else None ) - if langfuse_client - else None - ) - if context_manager is None: - return func(*args, **kwargs) + if context_manager is None: + return func(*args, **kwargs) - with context_manager as langfuse_span_or_generation: - is_return_type_generator = False + with context_manager as langfuse_span_or_generation: + is_return_type_generator = False - try: - result = func(*args, **kwargs) + try: + result = func(*args, **kwargs) - if capture_output is True: - if inspect.isgenerator(result): - is_return_type_generator = True + if capture_output is True: + if inspect.isgenerator(result): + is_return_type_generator = True - return self._wrap_sync_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_sync_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - if inspect.isasyncgen(result): - is_return_type_generator = True + if inspect.isasyncgen(result): + is_return_type_generator = True - return self._wrap_async_generator_result( - langfuse_span_or_generation, - result, - transform_to_string, - ) + return self._wrap_async_generator_result( + langfuse_span_or_generation, + result, + transform_to_string, + ) - langfuse_span_or_generation.update(output=result) + langfuse_span_or_generation.update(output=result) - return result - except Exception as e: - langfuse_span_or_generation.update( - level="ERROR", status_message=str(e) - ) + return result + except Exception as e: + langfuse_span_or_generation.update( + level="ERROR", status_message=str(e) + ) - raise e - finally: - if not is_return_type_generator: - langfuse_span_or_generation.end() + raise e + finally: + if not is_return_type_generator: + langfuse_span_or_generation.end() return cast(F, sync_wrapper) From ab0cbf318eb3d6cec228cccb83bf0ebfc5f69c24 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 12:25:55 +0200 Subject: [PATCH 09/66] add test --- tests/test_manual_graph_instrumentation.py | 198 +++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 tests/test_manual_graph_instrumentation.py diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py new file mode 100644 index 000000000..18cc87a3d --- /dev/null +++ b/tests/test_manual_graph_instrumentation.py @@ -0,0 +1,198 @@ +# Test manual graph instrumentation using Python SDK. + +import time + +import pytest + +from langfuse import Langfuse, observe +from tests.api_wrapper import LangfuseAPI +from tests.utils import create_uuid, get_api + + +def test_observe_type_agent_instrumentation(): + """Test @observe(type='AGENT') with the type-based approach. + """ + langfuse = Langfuse() + api = get_api() + + trace_name = f"type_based_graph_test_{create_uuid()}" + + @observe(type="GENERATION") + def start_agent(): + print("🔍 Executing start_agent function") + time.sleep(0.1) + return {"status": "started", "data": "initial_data"} + + @observe(type="RETRIEVER") + def process_agent(): + print("🔍 Executing process_agent function") + time.sleep(0.1) + return {"status": "processed", "data": "processed_data"} + + @observe(type="TOOL") + def tool_call(): + print("🔍 Executing tool_call function") + time.sleep(0.1) + return {"status": "intermediate", "data": "intermediate_data"} + + @observe(type="GENERATION") + def end_agent(): + print("🔍 Executing end_agent function") + time.sleep(0.1) + return {"status": "completed", "data": "final_data"} + + # Run the workflow within a trace context + with langfuse.start_as_current_span( + name="agent_workflow", as_type="AGENT" + ) as root_span: + langfuse.update_current_trace(name=trace_name) + + start_result = start_agent() + process_result = process_agent() + tool_result = tool_call() + end_result = end_agent() + + workflow_result = { + "start": start_result, + "process": process_result, + "tool": tool_result, + "end": end_result, + } + + langfuse.flush() + time.sleep(0.5) + + traces = api.trace.list(limit=50) + test_trace = None + for i, trace_data in enumerate(traces.data): + if trace_data.name == trace_name: + test_trace = trace_data + break + + assert test_trace is not None, f"Could not find trace with name {trace_name}" + + # Get the trace details including observations + trace_details = api.trace.get(test_trace.id) + all_observations = trace_details.observations + + agent_observations = [ + obs + for obs in all_observations + if obs.type in ["AGENT", "TOOL", "RETRIEVER", "CHAIN", "EMBEDDING"] + ] + + assert ( + len(agent_observations) == 4 + ), f"Expected 4 observations, got {len(agent_observations)} out of {len(all_observations)} total observations" + + # for agent_obs in agent_observations: + # print( + # f"{agent_obs.name} ({agent_obs.type}): {agent_obs.start_time} - {agent_obs.end_time}" + # ) + +def test_observe_parallel_tool_execution(): + """Test parallel tool execution where an agent starts multiple tools simultaneously. + + Creates a graph structure: + start_agent -> [tool_1, tool_2, tool_3] -> end_agent + """ + + langfuse = Langfuse() + api = get_api() + + trace_name = f"parallel_tools_test_{create_uuid()}" + + @observe(type="AGENT") + def start_agent(): + time.sleep(0.05) + return {"status": "tools_initiated", "tool_count": 3} + + @observe(type="TOOL") + def search_tool(): + time.sleep(0.2) + return {"tool": "search", "results": ["result1", "result2"]} + + @observe(type="TOOL") + def calculation_tool(): + time.sleep(0.15) + return {"tool": "calc", "result": 42} + + @observe(type="TOOL") + def api_tool(): + time.sleep(0.1) + return {"tool": "api", "data": {"status": "success"}} + + @observe(type="AGENT") + def end_agent(): + time.sleep(0.05) + return {"status": "completed", "summary": "all_tools_processed"} + + # Execute the parallel workflow + with langfuse.start_as_current_span( + name="parallel_workflow", as_type="SPAN" + ) as root_span: + langfuse.update_current_trace(name=trace_name) + start_result = start_agent() + + # execute tools in parallel - but keep them in the same trace context + # we simulate parallel execution with staggered starts + + search_result = search_tool() + time.sleep(0.01) + calc_result = calculation_tool() + time.sleep(0.01) + api_result = api_tool() + + tool_results = { + "search": search_result, + "calculation": calc_result, + "api": api_result, + } + + end_result = end_agent() + + workflow_result = { + "start": start_result, + "tools": tool_results, + "end": end_result, + } + + langfuse.flush() + time.sleep(0.5) + + traces = api.trace.list(limit=50) + test_trace = None + + for i, trace_data in enumerate(traces.data): + if trace_data.name == trace_name: + test_trace = trace_data + break + + assert test_trace is not None, f"Could not find trace with name {trace_name}" + + # Get trace details and filter observations + trace_details = api.trace.get(test_trace.id) + all_observations = trace_details.observations + + graph_observations = [ + obs for obs in all_observations if obs.type in ["AGENT", "TOOL"] + ] + + # Should have: start_agent (1) + 3 tools (3) + end_agent (1) = 5 total + expected_count = 5 + assert ( + len(graph_observations) == expected_count + ), f"Expected {expected_count} graph observations, got {len(graph_observations)} out of {len(all_observations)} total" + + # for obs in sorted(graph_observations, key=lambda x: x.start_time): + # print(f" {obs.name} ({obs.type}): {obs.start_time} - {obs.end_time}") + + agent_observations = [obs for obs in graph_observations if obs.type == "AGENT"] + tool_observations = [obs for obs in graph_observations if obs.type == "TOOL"] + + assert ( + len(agent_observations) == 2 + ), f"Expected 2 AGENT observations, got {len(agent_observations)}" + assert ( + len(tool_observations) == 3 + ), f"Expected 3 TOOL observations, got {len(tool_observations)}" From 81b255ac62e7238cbb619a2550ea28cea2ff5b48 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 15:12:14 +0200 Subject: [PATCH 10/66] lower case --- langfuse/_client/client.py | 49 ++++++++++--------- langfuse/_client/constants.py | 16 +++--- langfuse/_client/observe.py | 51 ++++++++++--------- langfuse/_client/span.py | 24 ++++----- tests/test_manual_graph_instrumentation.py | 57 +++++++++++----------- 5 files changed, 101 insertions(+), 96 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index ce7d2521c..f05171552 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -359,14 +359,12 @@ def start_as_current_span( Literal[ "generation", "span", - "GENERATION", - "EVENT", - "SPAN", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", ] ], ) -> _AgnosticContextManager[LangfuseSpan]: @@ -691,30 +689,30 @@ def _get_span_class( "span", "generation", "event", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "agent", + "tool", + "chain", + "retriever", + "embedding", ], ): """Get the appropriate span class based on as_type.""" # TODO: make it case insensitive - if as_type == "AGENT": + if as_type == "agent": return LangfuseAgent - elif as_type == "TOOL": + elif as_type == "tool": return LangfuseTool - elif as_type == "CHAIN": + elif as_type == "chain": return LangfuseChain - elif as_type == "RETRIEVER": + elif as_type == "retriever": return LangfuseRetriever - elif as_type == "EMBEDDING": + elif as_type == "embedding": return LangfuseEmbedding - elif as_type in ("generation", "GENERATION"): + elif as_type in ("generation"): return LangfuseGeneration - elif as_type in ("event", "EVENT"): + elif as_type in ("event"): return LangfuseEvent - elif as_type in ("span", "SPAN"): + elif as_type in ("span"): return LangfuseSpan else: return LangfuseSpan @@ -775,7 +773,14 @@ def _start_as_current_otel_span_with_processed_media( name: str, as_type: Optional[ Literal[ - "generation", "span", "event", "AGENT", "TOOL", "CHAIN", "RETRIEVER" + "generation", + "span", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", ] ] = None, end_on_exit: Optional[bool] = None, diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 7ab4e558c..97517865f 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -7,12 +7,12 @@ # Valid observation types for the @observe decorator VALID_OBSERVATION_TYPES = { - "SPAN", - "EVENT", - "GENERATION", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "span", + "event", + "generation", + "agent", + "tool", + "chain", + "retriever", + "embedding", } diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 8f25c8207..3de5b8390 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -70,14 +70,14 @@ def observe( as_type: Optional[Literal["generation"]] = None, type: Optional[ Literal[ - "SPAN", - "EVENT", - "GENERATION", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "span", + "event", + "generation", + "agent", + "tool", + "chain", + "retriever", + "embedding", ] ] = None, capture_input: Optional[bool] = None, @@ -93,14 +93,14 @@ def observe( as_type: Optional[Literal["generation"]] = None, type: Optional[ Literal[ - "SPAN", - "EVENT", - "GENERATION", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "span", + "event", + "generation", + "agent", + "tool", + "chain", + "retriever", + "embedding", ] ] = None, capture_input: Optional[bool] = None, @@ -122,7 +122,7 @@ def observe( as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span with model metrics support, suitable for tracking language model outputs. type (Optional[Literal]): Set the observation type for agentic workflows. Supported values: - "GENERATION", "AGENT", "TOOL", "CHAIN", "RETRIEVER", "EMBEDDING". When specified, creates spans with + "generation", "agent", "tool", "chain", "retriever", "embedding". When specified, creates spans with the specified type for graph visualization and filtering in the Langfuse UI. Returns: @@ -151,7 +151,7 @@ async def generate_answer(query): For automatic graph instrumentation with agent workflows: ```python - @observe(type="AGENT") + @observe(type="agent") def planning_agent(): return create_plan() ``` @@ -259,15 +259,14 @@ def _async_observe( name: Optional[str], as_type: Optional[ Literal[ + "span", "generation", - "GENERATION", - "EVENT", - "SPAN", - "AGENT", - "TOOL", - "CHAIN", - "RETRIEVER", - "EMBEDDING", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", ] ], capture_input: bool, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index fcfa681c9..49d66aa34 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1224,7 +1224,7 @@ class LangfuseGraphObservation(LangfuseSpanWrapper): """Base class for agentic workflow observations. This class provides a common foundation for specialized observation types - used in agentic workflows: AGENT, TOOL, CHAIN, RETRIEVER, and EMBEDDING. + used in agentic workflows: agent, tool, chain, retriever, and embedding. All graph observations use span-type attributes but with specific observation types. """ @@ -1245,7 +1245,7 @@ def __init__( """Initialize a new graph observation span. Args: - observation_type: The specific observation type (e.g., "AGENT", "TOOL") + observation_type: The specific observation type (e.g., "agent", "tool", ...) otel_span: The OpenTelemetry span to wrap langfuse_client: Reference to the parent Langfuse client input: Input data for the observation @@ -1331,45 +1331,45 @@ def update( class LangfuseAgent(LangfuseGraphObservation): - """Specialized span for AGENT observations in agentic workflows.""" + """Specialized span for agent observations in agentic workflows.""" def __init__(self, **kwargs): """Initialize a new LangfuseAgent span.""" - kwargs["observation_type"] = "AGENT" + kwargs["observation_type"] = "agent" super().__init__(**kwargs) class LangfuseTool(LangfuseGraphObservation): - """Specialized span for TOOL observations in agentic workflows.""" + """Specialized span for tool observations in agentic workflows.""" def __init__(self, **kwargs): """Initialize a new LangfuseTool span.""" - kwargs["observation_type"] = "TOOL" + kwargs["observation_type"] = "tool" super().__init__(**kwargs) class LangfuseChain(LangfuseGraphObservation): - """Specialized span for CHAIN observations in agentic workflows.""" + """Specialized span for chain observations in agentic workflows.""" def __init__(self, **kwargs): """Initialize a new LangfuseChain span.""" - kwargs["observation_type"] = "CHAIN" + kwargs["observation_type"] = "chain" super().__init__(**kwargs) class LangfuseRetriever(LangfuseGraphObservation): - """Specialized span for RETRIEVER observations in agentic workflows.""" + """Specialized span for retriever observations in agentic workflows.""" def __init__(self, **kwargs): """Initialize a new LangfuseRetriever span.""" - kwargs["observation_type"] = "RETRIEVER" + kwargs["observation_type"] = "retriever" super().__init__(**kwargs) class LangfuseEmbedding(LangfuseGraphObservation): - """Specialized span for EMBEDDING observations in agentic workflows.""" + """Specialized span for embedding observations in agentic workflows.""" def __init__(self, **kwargs): """Initialize a new LangfuseEmbedding span.""" - kwargs["observation_type"] = "EMBEDDING" + kwargs["observation_type"] = "embedding" super().__init__(**kwargs) diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index 18cc87a3d..bbf414df8 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -1,49 +1,40 @@ -# Test manual graph instrumentation using Python SDK. - import time -import pytest - from langfuse import Langfuse, observe from tests.api_wrapper import LangfuseAPI from tests.utils import create_uuid, get_api def test_observe_type_agent_instrumentation(): - """Test @observe(type='AGENT') with the type-based approach. - """ + """Test @observe(type='agent') with the type-based approach.""" langfuse = Langfuse() api = get_api() trace_name = f"type_based_graph_test_{create_uuid()}" - @observe(type="GENERATION") + @observe(type="generation") def start_agent(): - print("🔍 Executing start_agent function") time.sleep(0.1) return {"status": "started", "data": "initial_data"} - @observe(type="RETRIEVER") + @observe(type="retriever") def process_agent(): - print("🔍 Executing process_agent function") time.sleep(0.1) return {"status": "processed", "data": "processed_data"} - @observe(type="TOOL") + @observe(type="tool") def tool_call(): - print("🔍 Executing tool_call function") time.sleep(0.1) return {"status": "intermediate", "data": "intermediate_data"} - @observe(type="GENERATION") + @observe(type="generation") def end_agent(): - print("🔍 Executing end_agent function") time.sleep(0.1) return {"status": "completed", "data": "final_data"} # Run the workflow within a trace context with langfuse.start_as_current_span( - name="agent_workflow", as_type="AGENT" + name="agent_workflow", as_type="agent" ) as root_span: langfuse.update_current_trace(name=trace_name) @@ -78,7 +69,7 @@ def end_agent(): agent_observations = [ obs for obs in all_observations - if obs.type in ["AGENT", "TOOL", "RETRIEVER", "CHAIN", "EMBEDDING"] + if obs.type in ["agent", "tool", "retriever", "chain", "embedding"] ] assert ( @@ -90,7 +81,8 @@ def end_agent(): # f"{agent_obs.name} ({agent_obs.type}): {agent_obs.start_time} - {agent_obs.end_time}" # ) -def test_observe_parallel_tool_execution(): + +def test_observe_type_parallel_tool_execution(): """Test parallel tool execution where an agent starts multiple tools simultaneously. Creates a graph structure: @@ -102,34 +94,34 @@ def test_observe_parallel_tool_execution(): trace_name = f"parallel_tools_test_{create_uuid()}" - @observe(type="AGENT") + @observe(type="agent") def start_agent(): time.sleep(0.05) return {"status": "tools_initiated", "tool_count": 3} - @observe(type="TOOL") + @observe(type="tool") def search_tool(): time.sleep(0.2) return {"tool": "search", "results": ["result1", "result2"]} - @observe(type="TOOL") + @observe(type="tool") def calculation_tool(): time.sleep(0.15) return {"tool": "calc", "result": 42} - @observe(type="TOOL") + @observe(type="tool") def api_tool(): time.sleep(0.1) return {"tool": "api", "data": {"status": "success"}} - @observe(type="AGENT") + @observe(type="agent") def end_agent(): time.sleep(0.05) return {"status": "completed", "summary": "all_tools_processed"} # Execute the parallel workflow with langfuse.start_as_current_span( - name="parallel_workflow", as_type="SPAN" + name="parallel_workflow", as_type="span" ) as root_span: langfuse.update_current_trace(name=trace_name) start_result = start_agent() @@ -175,8 +167,12 @@ def end_agent(): all_observations = trace_details.observations graph_observations = [ - obs for obs in all_observations if obs.type in ["AGENT", "TOOL"] + obs + for obs in all_observations + if obs.type in ["agent", "tool", "AGENT", "TOOL"] ] + print(all_observations) + print(graph_observations) # Should have: start_agent (1) + 3 tools (3) + end_agent (1) = 5 total expected_count = 5 @@ -187,12 +183,17 @@ def end_agent(): # for obs in sorted(graph_observations, key=lambda x: x.start_time): # print(f" {obs.name} ({obs.type}): {obs.start_time} - {obs.end_time}") - agent_observations = [obs for obs in graph_observations if obs.type == "AGENT"] - tool_observations = [obs for obs in graph_observations if obs.type == "TOOL"] + agent_observations = [obs for obs in graph_observations if obs.type == "agent"] + tool_observations = [obs for obs in graph_observations if obs.type == "tool"] assert ( len(agent_observations) == 2 - ), f"Expected 2 AGENT observations, got {len(agent_observations)}" + ), f"Expected 2 agent observations, got {len(agent_observations)}" assert ( len(tool_observations) == 3 - ), f"Expected 3 TOOL observations, got {len(tool_observations)}" + ), f"Expected 3 tool observations, got {len(tool_observations)}" + + +if __name__ == "__main__": + test_observe_type_agent_instrumentation() + test_observe_type_parallel_tool_execution() From b164e41803637d923ecb04d811ef8041a9d7fce3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 15:20:56 +0200 Subject: [PATCH 11/66] fix lint --- langfuse/_client/client.py | 5 ++--- langfuse/_client/observe.py | 14 ++++---------- langfuse/_client/span.py | 10 +++++----- tests/test_manual_graph_instrumentation.py | 14 ++++---------- 4 files changed, 15 insertions(+), 28 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index f05171552..dcc6e7783 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -366,7 +366,7 @@ def start_as_current_span( "retriever", "embedding", ] - ], + ] = None, ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -695,9 +695,8 @@ def _get_span_class( "retriever", "embedding", ], - ): + ) -> type: """Get the appropriate span class based on as_type.""" - # TODO: make it case insensitive if as_type == "agent": return LangfuseAgent elif as_type == "tool": diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 3de5b8390..d9d6310f7 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -303,9 +303,6 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: with _set_current_public_key(public_key): langfuse_client = get_client(public_key=public_key) - # Use consolidated as_type parameter - final_obs_type = as_type - context_manager: Optional[ Union[ _AgnosticContextManager[LangfuseGeneration], @@ -319,13 +316,13 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early ) - if final_obs_type in ("generation", "GENERATION") + if as_type == "generation" else langfuse_client.start_as_current_span( name=final_name, trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=final_obs_type, + as_type=as_type, ) ) if langfuse_client @@ -413,9 +410,6 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: with _set_current_public_key(public_key): langfuse_client = get_client(public_key=public_key) - # Use consolidated as_type parameter - final_obs_type = as_type - context_manager: Optional[ Union[ _AgnosticContextManager[LangfuseGeneration], @@ -429,13 +423,13 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early ) - if final_obs_type in ("generation", "GENERATION") + if as_type == "generation" else langfuse_client.start_as_current_span( name=final_name, trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=final_obs_type, + as_type=as_type, ) ) if langfuse_client diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 49d66aa34..6b50a59aa 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1333,7 +1333,7 @@ def update( class LangfuseAgent(LangfuseGraphObservation): """Specialized span for agent observations in agentic workflows.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize a new LangfuseAgent span.""" kwargs["observation_type"] = "agent" super().__init__(**kwargs) @@ -1342,7 +1342,7 @@ def __init__(self, **kwargs): class LangfuseTool(LangfuseGraphObservation): """Specialized span for tool observations in agentic workflows.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize a new LangfuseTool span.""" kwargs["observation_type"] = "tool" super().__init__(**kwargs) @@ -1351,7 +1351,7 @@ def __init__(self, **kwargs): class LangfuseChain(LangfuseGraphObservation): """Specialized span for chain observations in agentic workflows.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize a new LangfuseChain span.""" kwargs["observation_type"] = "chain" super().__init__(**kwargs) @@ -1360,7 +1360,7 @@ def __init__(self, **kwargs): class LangfuseRetriever(LangfuseGraphObservation): """Specialized span for retriever observations in agentic workflows.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize a new LangfuseRetriever span.""" kwargs["observation_type"] = "retriever" super().__init__(**kwargs) @@ -1369,7 +1369,7 @@ def __init__(self, **kwargs): class LangfuseEmbedding(LangfuseGraphObservation): """Specialized span for embedding observations in agentic workflows.""" - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: """Initialize a new LangfuseEmbedding span.""" kwargs["observation_type"] = "embedding" super().__init__(**kwargs) diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index bbf414df8..578138e78 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -1,7 +1,6 @@ import time from langfuse import Langfuse, observe -from tests.api_wrapper import LangfuseAPI from tests.utils import create_uuid, get_api @@ -35,7 +34,7 @@ def end_agent(): # Run the workflow within a trace context with langfuse.start_as_current_span( name="agent_workflow", as_type="agent" - ) as root_span: + ): langfuse.update_current_trace(name=trace_name) start_result = start_agent() @@ -43,7 +42,7 @@ def end_agent(): tool_result = tool_call() end_result = end_agent() - workflow_result = { + _workflow_result = { "start": start_result, "process": process_result, "tool": tool_result, @@ -122,7 +121,7 @@ def end_agent(): # Execute the parallel workflow with langfuse.start_as_current_span( name="parallel_workflow", as_type="span" - ) as root_span: + ): langfuse.update_current_trace(name=trace_name) start_result = start_agent() @@ -143,7 +142,7 @@ def end_agent(): end_result = end_agent() - workflow_result = { + _workflow_result = { "start": start_result, "tools": tool_results, "end": end_result, @@ -171,8 +170,6 @@ def end_agent(): for obs in all_observations if obs.type in ["agent", "tool", "AGENT", "TOOL"] ] - print(all_observations) - print(graph_observations) # Should have: start_agent (1) + 3 tools (3) + end_agent (1) = 5 total expected_count = 5 @@ -194,6 +191,3 @@ def end_agent(): ), f"Expected 3 tool observations, got {len(tool_observations)}" -if __name__ == "__main__": - test_observe_type_agent_instrumentation() - test_observe_type_parallel_tool_execution() From ef49cde3f1a68aafdd51b3dd0fba2bd7b1facd1d Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 15:21:15 +0200 Subject: [PATCH 12/66] format --- tests/test_manual_graph_instrumentation.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index 578138e78..a2530ff96 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -32,9 +32,7 @@ def end_agent(): return {"status": "completed", "data": "final_data"} # Run the workflow within a trace context - with langfuse.start_as_current_span( - name="agent_workflow", as_type="agent" - ): + with langfuse.start_as_current_span(name="agent_workflow", as_type="agent"): langfuse.update_current_trace(name=trace_name) start_result = start_agent() @@ -119,9 +117,7 @@ def end_agent(): return {"status": "completed", "summary": "all_tools_processed"} # Execute the parallel workflow - with langfuse.start_as_current_span( - name="parallel_workflow", as_type="span" - ): + with langfuse.start_as_current_span(name="parallel_workflow", as_type="span"): langfuse.update_current_trace(name=trace_name) start_result = start_agent() @@ -189,5 +185,3 @@ def end_agent(): assert ( len(tool_observations) == 3 ), f"Expected 3 tool observations, got {len(tool_observations)}" - - From 8af5b67ea2de12187f90b0bef333ac9a67497302 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 15:55:22 +0200 Subject: [PATCH 13/66] types --- langfuse/_client/observe.py | 13 ++++++++++++- langfuse/_client/span.py | 10 +++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index d9d6310f7..8bea0ca76 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -377,7 +377,18 @@ def _sync_observe( func: F, *, name: Optional[str], - as_type: Optional[str], + as_type: Optional[ + Literal[ + "span", + "generation", + "event", + "agent", + "tool", + "chain", + "retriever", + "embedding", + ] + ], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 6b50a59aa..c550eeab3 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1333,7 +1333,7 @@ def update( class LangfuseAgent(LangfuseGraphObservation): """Specialized span for agent observations in agentic workflows.""" - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseAgent span.""" kwargs["observation_type"] = "agent" super().__init__(**kwargs) @@ -1342,7 +1342,7 @@ def __init__(self, **kwargs) -> None: class LangfuseTool(LangfuseGraphObservation): """Specialized span for tool observations in agentic workflows.""" - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseTool span.""" kwargs["observation_type"] = "tool" super().__init__(**kwargs) @@ -1351,7 +1351,7 @@ def __init__(self, **kwargs) -> None: class LangfuseChain(LangfuseGraphObservation): """Specialized span for chain observations in agentic workflows.""" - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseChain span.""" kwargs["observation_type"] = "chain" super().__init__(**kwargs) @@ -1360,7 +1360,7 @@ def __init__(self, **kwargs) -> None: class LangfuseRetriever(LangfuseGraphObservation): """Specialized span for retriever observations in agentic workflows.""" - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseRetriever span.""" kwargs["observation_type"] = "retriever" super().__init__(**kwargs) @@ -1369,7 +1369,7 @@ def __init__(self, **kwargs) -> None: class LangfuseEmbedding(LangfuseGraphObservation): """Specialized span for embedding observations in agentic workflows.""" - def __init__(self, **kwargs) -> None: + def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEmbedding span.""" kwargs["observation_type"] = "embedding" super().__init__(**kwargs) From bdb8147883ee612b3aade0a4a5d34d6f9365f3d3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 12 Aug 2025 20:38:25 +0200 Subject: [PATCH 14/66] cleanup --- langfuse/_client/client.py | 12 ++++-------- langfuse/_client/observe.py | 8 ++------ tests/test_manual_graph_instrumentation.py | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index dcc6e7783..01497fe87 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -707,13 +707,11 @@ def _get_span_class( return LangfuseRetriever elif as_type == "embedding": return LangfuseEmbedding - elif as_type in ("generation"): + elif as_type == "generation": return LangfuseGeneration - elif as_type in ("event"): + elif as_type == "event": return LangfuseEvent - elif as_type in ("span"): - return LangfuseSpan - else: + elif as_type == "span": return LangfuseSpan @_agnosticcontextmanager @@ -825,6 +823,7 @@ def _start_as_current_otel_span_with_processed_media( } ) elif span_class in [ + LangfuseSpan, LangfuseAgent, LangfuseTool, LangfuseChain, @@ -833,9 +832,6 @@ def _start_as_current_otel_span_with_processed_media( ]: # set their type internally in the class pass - else: - if as_type is not None: - common_args["as_type"] = as_type yield span_class(**common_args) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 8bea0ca76..52ee25485 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -190,13 +190,9 @@ def sub_process(): raise ValueError( f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" ) - if as_type is not None and as_type.upper() not in VALID_OBSERVATION_TYPES: - valid_values = sorted( - list(VALID_OBSERVATION_TYPES) - + [t.lower() for t in VALID_OBSERVATION_TYPES] - ) + if as_type is not None and as_type not in VALID_OBSERVATION_TYPES: raise ValueError( - f"Invalid as_type '{as_type}'. Valid values are: {', '.join(valid_values)}" + f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" ) function_io_capture_enabled = os.environ.get( diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index a2530ff96..d63090e87 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -66,7 +66,7 @@ def end_agent(): agent_observations = [ obs for obs in all_observations - if obs.type in ["agent", "tool", "retriever", "chain", "embedding"] + if obs.type in ["agent", "tool", "retriever", "chain", "embedding", "AGENT", "TOOL", "RETRIEVER", "CHAIN", "EMBEDDING", "GENERATION", "generation"] ] assert ( From 089809515f69d62b817e0ce0ab142c3cc1bb5651 Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 13 Aug 2025 18:45:13 +0200 Subject: [PATCH 15/66] fix test --- langfuse/__init__.py | 7 +- langfuse/_client/client.py | 2 +- poetry.lock | 2565 ------------------------------------ 3 files changed, 7 insertions(+), 2567 deletions(-) delete mode 100644 poetry.lock diff --git a/langfuse/__init__.py b/langfuse/__init__.py index 5d8da4cc2..3359f9d18 100644 --- a/langfuse/__init__.py +++ b/langfuse/__init__.py @@ -4,7 +4,7 @@ from ._client.attributes import LangfuseOtelSpanAttributes from ._client.get_client import get_client from ._client.observe import observe -from ._client.span import LangfuseEvent, LangfuseGeneration, LangfuseSpan +from ._client.span import LangfuseEvent, LangfuseGeneration, LangfuseSpan, LangfuseAgent, LangfuseTool, LangfuseChain, LangfuseEmbedding, LangfuseRetriever Langfuse = _client_module.Langfuse @@ -16,4 +16,9 @@ "LangfuseGeneration", "LangfuseEvent", "LangfuseOtelSpanAttributes", + "LangfuseAgent", + "LangfuseTool", + "LangfuseChain", + "LangfuseEmbedding", + "LangfuseRetriever", ] diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 01497fe87..511e84c76 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -432,7 +432,7 @@ def start_as_current_span( return cast( _AgnosticContextManager[LangfuseSpan], self._start_as_current_otel_span_with_processed_media( - as_type=as_type, + as_type="span", name=name, end_on_exit=end_on_exit, input=input, diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 007b7fdbd..000000000 --- a/poetry.lock +++ /dev/null @@ -1,2565 +0,0 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.10.0" -description = "High-level concurrency and networking framework on top of asyncio or Trio" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}, - {file = "anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} - -[package.extras] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "async-timeout" -version = "4.0.3" -description = "Timeout context manager for asyncio programs" -optional = true -python-versions = ">=3.7" -groups = ["main"] -markers = "extra == \"langchain\" and python_version < \"3.11\"" -files = [ - {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, - {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, -] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -groups = ["main"] -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "certifi" -version = "2025.8.3" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, - {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] -markers = {main = "extra == \"langchain\" and platform_python_implementation == \"PyPy\"", dev = "platform_python_implementation == \"PyPy\""} - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.2" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-win32.whl", hash = "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a"}, - {file = "charset_normalizer-3.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a"}, - {file = "charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c"}, - {file = "charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7"}, - {file = "charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-win32.whl", hash = "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58"}, - {file = "charset_normalizer-3.4.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-win32.whl", hash = "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7"}, - {file = "charset_normalizer-3.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471"}, - {file = "charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e"}, - {file = "charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0"}, - {file = "charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev"] -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -markers = {main = "extra == \"openai\" and platform_system == \"Windows\"", dev = "platform_system == \"Windows\" or sys_platform == \"win32\""} - -[[package]] -name = "distlib" -version = "0.4.0" -description = "Distribution utilities" -optional = false -python-versions = "*" -groups = ["dev"] -files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, -] - -[[package]] -name = "distro" -version = "1.9.0" -description = "Distro - an OS platform information API" -optional = false -python-versions = ">=3.6" -groups = ["main", "dev"] -files = [ - {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, - {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, -] -markers = {main = "extra == \"openai\""} - -[[package]] -name = "exceptiongroup" -version = "1.3.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "execnet" -version = "2.1.1" -description = "execnet: rapid multi-Python deployment" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, - {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, -] - -[package.extras] -testing = ["hatch", "pre-commit", "pytest", "tox"] - -[[package]] -name = "filelock" -version = "3.18.0" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, - {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] -typing = ["typing-extensions (>=4.12.2) ; python_version < \"3.11\""] - -[[package]] -name = "googleapis-common-protos" -version = "1.70.0" -description = "Common protobufs used in Google APIs" -optional = false -python-versions = ">=3.7" -groups = ["main"] -files = [ - {file = "googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8"}, - {file = "googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257"}, -] - -[package.dependencies] -protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" - -[package.extras] -grpc = ["grpcio (>=1.44.0,<2.0.0)"] - -[[package]] -name = "greenlet" -version = "3.2.4" -description = "Lightweight in-process concurrent programming" -optional = true -python-versions = ">=3.9" -groups = ["main"] -markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") and extra == \"langchain\"" -files = [ - {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"}, - {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"}, - {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"}, - {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"}, - {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"}, - {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"}, - {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"}, - {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"}, - {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"}, - {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"}, - {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"}, - {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"}, - {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"}, - {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil", "setuptools"] - -[[package]] -name = "grpcio" -version = "1.74.0" -description = "HTTP/2-based RPC framework" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "grpcio-1.74.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:85bd5cdf4ed7b2d6438871adf6afff9af7096486fcf51818a81b77ef4dd30907"}, - {file = "grpcio-1.74.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:68c8ebcca945efff9d86d8d6d7bfb0841cf0071024417e2d7f45c5e46b5b08eb"}, - {file = "grpcio-1.74.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:e154d230dc1bbbd78ad2fdc3039fa50ad7ffcf438e4eb2fa30bce223a70c7486"}, - {file = "grpcio-1.74.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8978003816c7b9eabe217f88c78bc26adc8f9304bf6a594b02e5a49b2ef9c11"}, - {file = "grpcio-1.74.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3d7bd6e3929fd2ea7fbc3f562e4987229ead70c9ae5f01501a46701e08f1ad9"}, - {file = "grpcio-1.74.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:136b53c91ac1d02c8c24201bfdeb56f8b3ac3278668cbb8e0ba49c88069e1bdc"}, - {file = "grpcio-1.74.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fe0f540750a13fd8e5da4b3eaba91a785eea8dca5ccd2bc2ffe978caa403090e"}, - {file = "grpcio-1.74.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4e4181bfc24413d1e3a37a0b7889bea68d973d4b45dd2bc68bb766c140718f82"}, - {file = "grpcio-1.74.0-cp310-cp310-win32.whl", hash = "sha256:1733969040989f7acc3d94c22f55b4a9501a30f6aaacdbccfaba0a3ffb255ab7"}, - {file = "grpcio-1.74.0-cp310-cp310-win_amd64.whl", hash = "sha256:9e912d3c993a29df6c627459af58975b2e5c897d93287939b9d5065f000249b5"}, - {file = "grpcio-1.74.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:69e1a8180868a2576f02356565f16635b99088da7df3d45aaa7e24e73a054e31"}, - {file = "grpcio-1.74.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:8efe72fde5500f47aca1ef59495cb59c885afe04ac89dd11d810f2de87d935d4"}, - {file = "grpcio-1.74.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a8f0302f9ac4e9923f98d8e243939a6fb627cd048f5cd38595c97e38020dffce"}, - {file = "grpcio-1.74.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f609a39f62a6f6f05c7512746798282546358a37ea93c1fcbadf8b2fed162e3"}, - {file = "grpcio-1.74.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c98e0b7434a7fa4e3e63f250456eaef52499fba5ae661c58cc5b5477d11e7182"}, - {file = "grpcio-1.74.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:662456c4513e298db6d7bd9c3b8df6f75f8752f0ba01fb653e252ed4a59b5a5d"}, - {file = "grpcio-1.74.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3d14e3c4d65e19d8430a4e28ceb71ace4728776fd6c3ce34016947474479683f"}, - {file = "grpcio-1.74.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bf949792cee20d2078323a9b02bacbbae002b9e3b9e2433f2741c15bdeba1c4"}, - {file = "grpcio-1.74.0-cp311-cp311-win32.whl", hash = "sha256:55b453812fa7c7ce2f5c88be3018fb4a490519b6ce80788d5913f3f9d7da8c7b"}, - {file = "grpcio-1.74.0-cp311-cp311-win_amd64.whl", hash = "sha256:86ad489db097141a907c559988c29718719aa3e13370d40e20506f11b4de0d11"}, - {file = "grpcio-1.74.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8533e6e9c5bd630ca98062e3a1326249e6ada07d05acf191a77bc33f8948f3d8"}, - {file = "grpcio-1.74.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:2918948864fec2a11721d91568effffbe0a02b23ecd57f281391d986847982f6"}, - {file = "grpcio-1.74.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:60d2d48b0580e70d2e1954d0d19fa3c2e60dd7cbed826aca104fff518310d1c5"}, - {file = "grpcio-1.74.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3601274bc0523f6dc07666c0e01682c94472402ac2fd1226fd96e079863bfa49"}, - {file = "grpcio-1.74.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:176d60a5168d7948539def20b2a3adcce67d72454d9ae05969a2e73f3a0feee7"}, - {file = "grpcio-1.74.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e759f9e8bc908aaae0412642afe5416c9f983a80499448fcc7fab8692ae044c3"}, - {file = "grpcio-1.74.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9e7c4389771855a92934b2846bd807fc25a3dfa820fd912fe6bd8136026b2707"}, - {file = "grpcio-1.74.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cce634b10aeab37010449124814b05a62fb5f18928ca878f1bf4750d1f0c815b"}, - {file = "grpcio-1.74.0-cp312-cp312-win32.whl", hash = "sha256:885912559974df35d92219e2dc98f51a16a48395f37b92865ad45186f294096c"}, - {file = "grpcio-1.74.0-cp312-cp312-win_amd64.whl", hash = "sha256:42f8fee287427b94be63d916c90399ed310ed10aadbf9e2e5538b3e497d269bc"}, - {file = "grpcio-1.74.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:2bc2d7d8d184e2362b53905cb1708c84cb16354771c04b490485fa07ce3a1d89"}, - {file = "grpcio-1.74.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c14e803037e572c177ba54a3e090d6eb12efd795d49327c5ee2b3bddb836bf01"}, - {file = "grpcio-1.74.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:f6ec94f0e50eb8fa1744a731088b966427575e40c2944a980049798b127a687e"}, - {file = "grpcio-1.74.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:566b9395b90cc3d0d0c6404bc8572c7c18786ede549cdb540ae27b58afe0fb91"}, - {file = "grpcio-1.74.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1ea6176d7dfd5b941ea01c2ec34de9531ba494d541fe2057c904e601879f249"}, - {file = "grpcio-1.74.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:64229c1e9cea079420527fa8ac45d80fc1e8d3f94deaa35643c381fa8d98f362"}, - {file = "grpcio-1.74.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:0f87bddd6e27fc776aacf7ebfec367b6d49cad0455123951e4488ea99d9b9b8f"}, - {file = "grpcio-1.74.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3b03d8f2a07f0fea8c8f74deb59f8352b770e3900d143b3d1475effcb08eec20"}, - {file = "grpcio-1.74.0-cp313-cp313-win32.whl", hash = "sha256:b6a73b2ba83e663b2480a90b82fdae6a7aa6427f62bf43b29912c0cfd1aa2bfa"}, - {file = "grpcio-1.74.0-cp313-cp313-win_amd64.whl", hash = "sha256:fd3c71aeee838299c5887230b8a1822795325ddfea635edd82954c1eaa831e24"}, - {file = "grpcio-1.74.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:4bc5fca10aaf74779081e16c2bcc3d5ec643ffd528d9e7b1c9039000ead73bae"}, - {file = "grpcio-1.74.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:6bab67d15ad617aff094c382c882e0177637da73cbc5532d52c07b4ee887a87b"}, - {file = "grpcio-1.74.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:655726919b75ab3c34cdad39da5c530ac6fa32696fb23119e36b64adcfca174a"}, - {file = "grpcio-1.74.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a2b06afe2e50ebfd46247ac3ba60cac523f54ec7792ae9ba6073c12daf26f0a"}, - {file = "grpcio-1.74.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f251c355167b2360537cf17bea2cf0197995e551ab9da6a0a59b3da5e8704f9"}, - {file = "grpcio-1.74.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8f7b5882fb50632ab1e48cb3122d6df55b9afabc265582808036b6e51b9fd6b7"}, - {file = "grpcio-1.74.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:834988b6c34515545b3edd13e902c1acdd9f2465d386ea5143fb558f153a7176"}, - {file = "grpcio-1.74.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:22b834cef33429ca6cc28303c9c327ba9a3fafecbf62fae17e9a7b7163cc43ac"}, - {file = "grpcio-1.74.0-cp39-cp39-win32.whl", hash = "sha256:7d95d71ff35291bab3f1c52f52f474c632db26ea12700c2ff0ea0532cb0b5854"}, - {file = "grpcio-1.74.0-cp39-cp39-win_amd64.whl", hash = "sha256:ecde9ab49f58433abe02f9ed076c7b5be839cf0153883a6d23995937a82392fa"}, - {file = "grpcio-1.74.0.tar.gz", hash = "sha256:80d1f4fbb35b0742d3e3d3bb654b7381cd5f015f8497279a1e9c21ba623e01b1"}, -] - -[package.extras] -protobuf = ["grpcio-tools (>=1.74.0)"] - -[[package]] -name = "h11" -version = "0.16.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, - {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, - {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.16" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.28.1" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, - {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" - -[package.extras] -brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "identify" -version = "2.6.12" -description = "File identification library for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2"}, - {file = "identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -groups = ["main", "dev"] -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "importlib-metadata" -version = "8.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, - {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, -] - -[package.dependencies] -zipp = ">=3.20" - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] - -[[package]] -name = "iniconfig" -version = "2.1.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jiter" -version = "0.10.0" -description = "Fast iterable JSON parser." -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303"}, - {file = "jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90"}, - {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0"}, - {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee"}, - {file = "jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4"}, - {file = "jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5"}, - {file = "jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978"}, - {file = "jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606"}, - {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605"}, - {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5"}, - {file = "jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7"}, - {file = "jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812"}, - {file = "jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b"}, - {file = "jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95"}, - {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea"}, - {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b"}, - {file = "jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01"}, - {file = "jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49"}, - {file = "jiter-0.10.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0588107ec8e11b6f5ef0e0d656fb2803ac6cf94a96b2b9fc675c0e3ab5e8644"}, - {file = "jiter-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cafc4628b616dc32530c20ee53d71589816cf385dd9449633e910d596b1f5c8a"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520ef6d981172693786a49ff5b09eda72a42e539f14788124a07530f785c3ad6"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:554dedfd05937f8fc45d17ebdf298fe7e0c77458232bcb73d9fbbf4c6455f5b3"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc299da7789deacf95f64052d97f75c16d4fc8c4c214a22bf8d859a4288a1c2"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5161e201172de298a8a1baad95eb85db4fb90e902353b1f6a41d64ea64644e25"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2227db6ba93cb3e2bf67c87e594adde0609f146344e8207e8730364db27041"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15acb267ea5e2c64515574b06a8bf393fbfee6a50eb1673614aa45f4613c0cca"}, - {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:901b92f2e2947dc6dfcb52fd624453862e16665ea909a08398dde19c0731b7f4"}, - {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d0cb9a125d5a3ec971a094a845eadde2db0de85b33c9f13eb94a0c63d463879e"}, - {file = "jiter-0.10.0-cp313-cp313-win32.whl", hash = "sha256:48a403277ad1ee208fb930bdf91745e4d2d6e47253eedc96e2559d1e6527006d"}, - {file = "jiter-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:75f9eb72ecb640619c29bf714e78c9c46c9c4eaafd644bf78577ede459f330d4"}, - {file = "jiter-0.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:28ed2a4c05a1f32ef0e1d24c2611330219fed727dae01789f4a335617634b1ca"}, - {file = "jiter-0.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a4c418b1ec86a195f1ca69da8b23e8926c752b685af665ce30777233dfe070"}, - {file = "jiter-0.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d7bfed2fe1fe0e4dda6ef682cee888ba444b21e7a6553e03252e4feb6cf0adca"}, - {file = "jiter-0.10.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:5e9251a5e83fab8d87799d3e1a46cb4b7f2919b895c6f4483629ed2446f66522"}, - {file = "jiter-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:023aa0204126fe5b87ccbcd75c8a0d0261b9abdbbf46d55e7ae9f8e22424eeb8"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c189c4f1779c05f75fc17c0c1267594ed918996a231593a21a5ca5438445216"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15720084d90d1098ca0229352607cd68256c76991f6b374af96f36920eae13c4"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f2fb68e5f1cfee30e2b2a09549a00683e0fde4c6a2ab88c94072fc33cb7426"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce541693355fc6da424c08b7edf39a2895f58d6ea17d92cc2b168d20907dee12"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c50c40272e189d50006ad5c73883caabb73d4e9748a688b216e85a9a9ca3b9"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa3402a2ff9815960e0372a47b75c76979d74402448509ccd49a275fa983ef8a"}, - {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:1956f934dca32d7bb647ea21d06d93ca40868b505c228556d3373cbd255ce853"}, - {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:fcedb049bdfc555e261d6f65a6abe1d5ad68825b7202ccb9692636c70fcced86"}, - {file = "jiter-0.10.0-cp314-cp314-win32.whl", hash = "sha256:ac509f7eccca54b2a29daeb516fb95b6f0bd0d0d8084efaf8ed5dfc7b9f0b357"}, - {file = "jiter-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ed975b83a2b8639356151cef5c0d597c68376fc4922b45d0eb384ac058cfa00"}, - {file = "jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5"}, - {file = "jiter-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bd6292a43c0fc09ce7c154ec0fa646a536b877d1e8f2f96c19707f65355b5a4d"}, - {file = "jiter-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39de429dcaeb6808d75ffe9effefe96a4903c6a4b376b2f6d08d77c1aaee2f18"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52ce124f13a7a616fad3bb723f2bfb537d78239d1f7f219566dc52b6f2a9e48d"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:166f3606f11920f9a1746b2eea84fa2c0a5d50fd313c38bdea4edc072000b0af"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28dcecbb4ba402916034fc14eba7709f250c4d24b0c43fc94d187ee0580af181"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86c5aa6910f9bebcc7bc4f8bc461aff68504388b43bfe5e5c0bd21efa33b52f4"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ceeb52d242b315d7f1f74b441b6a167f78cea801ad7c11c36da77ff2d42e8a28"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff76d8887c8c8ee1e772274fcf8cc1071c2c58590d13e33bd12d02dc9a560397"}, - {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a9be4d0fa2b79f7222a88aa488bd89e2ae0a0a5b189462a12def6ece2faa45f1"}, - {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ab7fd8738094139b6c1ab1822d6f2000ebe41515c537235fd45dabe13ec9324"}, - {file = "jiter-0.10.0-cp39-cp39-win32.whl", hash = "sha256:5f51e048540dd27f204ff4a87f5d79294ea0aa3aa552aca34934588cf27023cf"}, - {file = "jiter-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b28302349dc65703a9e4ead16f163b1c339efffbe1049c30a44b001a2a4fff9"}, - {file = "jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500"}, -] -markers = {main = "extra == \"openai\""} - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -groups = ["main", "dev"] -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] -markers = {main = "extra == \"langchain\""} - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] -markers = {main = "extra == \"langchain\""} - -[[package]] -name = "langchain" -version = "0.3.27" -description = "Building applications with LLMs through composability" -optional = true -python-versions = "<4.0,>=3.9" -groups = ["main"] -markers = "extra == \"langchain\"" -files = [ - {file = "langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798"}, - {file = "langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62"}, -] - -[package.dependencies] -async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} -langchain-core = ">=0.3.72,<1.0.0" -langchain-text-splitters = ">=0.3.9,<1.0.0" -langsmith = ">=0.1.17" -pydantic = ">=2.7.4,<3.0.0" -PyYAML = ">=5.3" -requests = ">=2,<3" -SQLAlchemy = ">=1.4,<3" - -[package.extras] -anthropic = ["langchain-anthropic"] -aws = ["langchain-aws"] -azure-ai = ["langchain-azure-ai"] -cohere = ["langchain-cohere"] -community = ["langchain-community"] -deepseek = ["langchain-deepseek"] -fireworks = ["langchain-fireworks"] -google-genai = ["langchain-google-genai"] -google-vertexai = ["langchain-google-vertexai"] -groq = ["langchain-groq"] -huggingface = ["langchain-huggingface"] -mistralai = ["langchain-mistralai"] -ollama = ["langchain-ollama"] -openai = ["langchain-openai"] -perplexity = ["langchain-perplexity"] -together = ["langchain-together"] -xai = ["langchain-xai"] - -[[package]] -name = "langchain-core" -version = "0.3.74" -description = "Building applications with LLMs through composability" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "langchain_core-0.3.74-py3-none-any.whl", hash = "sha256:088338b5bc2f6a66892f9afc777992c24ee3188f41cbc603d09181e34a228ce7"}, - {file = "langchain_core-0.3.74.tar.gz", hash = "sha256:ff604441aeade942fbcc0a3860a592daba7671345230c2078ba2eb5f82b6ba76"}, -] -markers = {main = "extra == \"langchain\""} - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.3.45" -packaging = ">=23.2" -pydantic = ">=2.7.4" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0" -typing-extensions = ">=4.7" - -[[package]] -name = "langchain-openai" -version = "0.2.14" -description = "An integration package connecting OpenAI and LangChain" -optional = false -python-versions = "<4.0,>=3.9" -groups = ["dev"] -files = [ - {file = "langchain_openai-0.2.14-py3-none-any.whl", hash = "sha256:d232496662f79ece9a11caf7d798ba863e559c771bc366814f7688e0fe664fe8"}, - {file = "langchain_openai-0.2.14.tar.gz", hash = "sha256:7a514f309e356b182a337c0ed36ab3fbe34d9834a235a3b85cb7f91ae775d978"}, -] - -[package.dependencies] -langchain-core = ">=0.3.27,<0.4.0" -openai = ">=1.58.1,<2.0.0" -tiktoken = ">=0.7,<1" - -[[package]] -name = "langchain-text-splitters" -version = "0.3.9" -description = "LangChain text splitting utilities" -optional = true -python-versions = ">=3.9" -groups = ["main"] -markers = "extra == \"langchain\"" -files = [ - {file = "langchain_text_splitters-0.3.9-py3-none-any.whl", hash = "sha256:cee0bb816211584ea79cc79927317c358543f40404bcfdd69e69ba3ccde54401"}, - {file = "langchain_text_splitters-0.3.9.tar.gz", hash = "sha256:7cd1e5a3aaf609979583eeca2eb34177622570b8fa8f586a605c6b1c34e7ebdb"}, -] - -[package.dependencies] -langchain-core = ">=0.3.72,<1.0.0" - -[[package]] -name = "langgraph" -version = "0.2.76" -description = "Building stateful, multi-actor applications with LLMs" -optional = false -python-versions = "<4.0,>=3.9.0" -groups = ["dev"] -files = [ - {file = "langgraph-0.2.76-py3-none-any.whl", hash = "sha256:076b8b5d2fc5a9761c46a7618430cfa5c978a8012257c43cbc127b27e0fd7872"}, - {file = "langgraph-0.2.76.tar.gz", hash = "sha256:688f8dcd9b6797ba78384599e0de944773000c75156ad1e186490e99e89fa5c0"}, -] - -[package.dependencies] -langchain-core = ">=0.2.43,<0.3.0 || >0.3.0,<0.3.1 || >0.3.1,<0.3.2 || >0.3.2,<0.3.3 || >0.3.3,<0.3.4 || >0.3.4,<0.3.5 || >0.3.5,<0.3.6 || >0.3.6,<0.3.7 || >0.3.7,<0.3.8 || >0.3.8,<0.3.9 || >0.3.9,<0.3.10 || >0.3.10,<0.3.11 || >0.3.11,<0.3.12 || >0.3.12,<0.3.13 || >0.3.13,<0.3.14 || >0.3.14,<0.3.15 || >0.3.15,<0.3.16 || >0.3.16,<0.3.17 || >0.3.17,<0.3.18 || >0.3.18,<0.3.19 || >0.3.19,<0.3.20 || >0.3.20,<0.3.21 || >0.3.21,<0.3.22 || >0.3.22,<0.4.0" -langgraph-checkpoint = ">=2.0.10,<3.0.0" -langgraph-sdk = ">=0.1.42,<0.2.0" - -[[package]] -name = "langgraph-checkpoint" -version = "2.1.1" -description = "Library with base interfaces for LangGraph checkpoint savers." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "langgraph_checkpoint-2.1.1-py3-none-any.whl", hash = "sha256:5a779134fd28134a9a83d078be4450bbf0e0c79fdf5e992549658899e6fc5ea7"}, - {file = "langgraph_checkpoint-2.1.1.tar.gz", hash = "sha256:72038c0f9e22260cb9bff1f3ebe5eb06d940b7ee5c1e4765019269d4f21cf92d"}, -] - -[package.dependencies] -langchain-core = ">=0.2.38" -ormsgpack = ">=1.10.0" - -[[package]] -name = "langgraph-sdk" -version = "0.1.74" -description = "SDK for interacting with LangGraph API" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "langgraph_sdk-0.1.74-py3-none-any.whl", hash = "sha256:3a265c3757fe0048adad4391d10486db63ef7aa5a2cbd22da22d4503554cb890"}, - {file = "langgraph_sdk-0.1.74.tar.gz", hash = "sha256:7450e0db5b226cc2e5328ca22c5968725873630ef47c4206a30707cb25dc3ad6"}, -] - -[package.dependencies] -httpx = ">=0.25.2" -orjson = ">=3.10.1" - -[[package]] -name = "langsmith" -version = "0.4.13" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "langsmith-0.4.13-py3-none-any.whl", hash = "sha256:dab7b16ee16986995007bf5a777f45c18f8bf7453f67ae2ebcb46ce43c214297"}, - {file = "langsmith-0.4.13.tar.gz", hash = "sha256:1ae7dbb5d8150647406f49885a2dd16ab12bd990254b5dc23718838b3d086fde"}, -] -markers = {main = "extra == \"langchain\""} - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = {version = ">=3.9.14", markers = "platform_python_implementation != \"PyPy\""} -packaging = ">=23.2" -pydantic = ">=1,<3" -requests = ">=2.0.0" -requests-toolbelt = ">=1.0.0" -zstandard = ">=0.23.0" - -[package.extras] -langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2)"] -openai-agents = ["openai-agents (>=0.0.3)"] -otel = ["opentelemetry-api (>=1.30.0)", "opentelemetry-exporter-otlp-proto-http (>=1.30.0)", "opentelemetry-sdk (>=1.30.0)"] -pytest = ["pytest (>=7.0.0)", "rich (>=13.9.4)", "vcrpy (>=7.0.0)"] -vcr = ["vcrpy (>=7.0.0)"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -groups = ["dev", "docs"] -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "mypy" -version = "1.17.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972"}, - {file = "mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390"}, - {file = "mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94"}, - {file = "mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b"}, - {file = "mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5"}, - {file = "mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341"}, - {file = "mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb"}, - {file = "mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849"}, - {file = "mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14"}, - {file = "mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a"}, - {file = "mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91"}, - {file = "mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8"}, - {file = "mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259"}, - {file = "mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d"}, - {file = "mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9"}, - {file = "mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01"}, -] - -[package.dependencies] -mypy_extensions = ">=1.0.0" -pathspec = ">=0.9.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing_extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.1.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, - {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "openai" -version = "1.99.9" -description = "The official Python library for the openai API" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "openai-1.99.9-py3-none-any.whl", hash = "sha256:9dbcdb425553bae1ac5d947147bebbd630d91bbfc7788394d4c4f3a35682ab3a"}, - {file = "openai-1.99.9.tar.gz", hash = "sha256:f2082d155b1ad22e83247c3de3958eb4255b20ccf4a1de2e6681b6957b554e92"}, -] -markers = {main = "extra == \"openai\""} - -[package.dependencies] -anyio = ">=3.5.0,<5" -distro = ">=1.7.0,<2" -httpx = ">=0.23.0,<1" -jiter = ">=0.4.0,<1" -pydantic = ">=1.9.0,<3" -sniffio = "*" -tqdm = ">4" -typing-extensions = ">=4.11,<5" - -[package.extras] -aiohttp = ["aiohttp", "httpx-aiohttp (>=0.1.8)"] -datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -realtime = ["websockets (>=13,<16)"] -voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"] - -[[package]] -name = "opentelemetry-api" -version = "1.36.0" -description = "OpenTelemetry Python API" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_api-1.36.0-py3-none-any.whl", hash = "sha256:02f20bcacf666e1333b6b1f04e647dc1d5111f86b8e510238fcc56d7762cda8c"}, - {file = "opentelemetry_api-1.36.0.tar.gz", hash = "sha256:9a72572b9c416d004d492cbc6e61962c0501eaf945ece9b5a0f56597d8348aa0"}, -] - -[package.dependencies] -importlib-metadata = ">=6.0,<8.8.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-exporter-otlp" -version = "1.36.0" -description = "OpenTelemetry Collector Exporters" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_exporter_otlp-1.36.0-py3-none-any.whl", hash = "sha256:de93b7c45bcc78296998775d52add7c63729e83ef2cd6560730a6b336d7f6494"}, - {file = "opentelemetry_exporter_otlp-1.36.0.tar.gz", hash = "sha256:72f166ea5a8923ac42889337f903e93af57db8893de200369b07401e98e4e06b"}, -] - -[package.dependencies] -opentelemetry-exporter-otlp-proto-grpc = "1.36.0" -opentelemetry-exporter-otlp-proto-http = "1.36.0" - -[[package]] -name = "opentelemetry-exporter-otlp-proto-common" -version = "1.36.0" -description = "OpenTelemetry Protobuf encoding" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_exporter_otlp_proto_common-1.36.0-py3-none-any.whl", hash = "sha256:0fc002a6ed63eac235ada9aa7056e5492e9a71728214a61745f6ad04b923f840"}, - {file = "opentelemetry_exporter_otlp_proto_common-1.36.0.tar.gz", hash = "sha256:6c496ccbcbe26b04653cecadd92f73659b814c6e3579af157d8716e5f9f25cbf"}, -] - -[package.dependencies] -opentelemetry-proto = "1.36.0" - -[[package]] -name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.36.0" -description = "OpenTelemetry Collector Protobuf over gRPC Exporter" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_exporter_otlp_proto_grpc-1.36.0-py3-none-any.whl", hash = "sha256:734e841fc6a5d6f30e7be4d8053adb703c70ca80c562ae24e8083a28fadef211"}, - {file = "opentelemetry_exporter_otlp_proto_grpc-1.36.0.tar.gz", hash = "sha256:b281afbf7036b325b3588b5b6c8bb175069e3978d1bd24071f4a59d04c1e5bbf"}, -] - -[package.dependencies] -googleapis-common-protos = ">=1.57,<2.0" -grpcio = [ - {version = ">=1.63.2,<2.0.0", markers = "python_version < \"3.13\""}, - {version = ">=1.66.2,<2.0.0", markers = "python_version >= \"3.13\""}, -] -opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.36.0" -opentelemetry-proto = "1.36.0" -opentelemetry-sdk = ">=1.36.0,<1.37.0" -typing-extensions = ">=4.6.0" - -[[package]] -name = "opentelemetry-exporter-otlp-proto-http" -version = "1.36.0" -description = "OpenTelemetry Collector Protobuf over HTTP Exporter" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_exporter_otlp_proto_http-1.36.0-py3-none-any.whl", hash = "sha256:3d769f68e2267e7abe4527f70deb6f598f40be3ea34c6adc35789bea94a32902"}, - {file = "opentelemetry_exporter_otlp_proto_http-1.36.0.tar.gz", hash = "sha256:dd3637f72f774b9fc9608ab1ac479f8b44d09b6fb5b2f3df68a24ad1da7d356e"}, -] - -[package.dependencies] -googleapis-common-protos = ">=1.52,<2.0" -opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.36.0" -opentelemetry-proto = "1.36.0" -opentelemetry-sdk = ">=1.36.0,<1.37.0" -requests = ">=2.7,<3.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-proto" -version = "1.36.0" -description = "OpenTelemetry Python Proto" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_proto-1.36.0-py3-none-any.whl", hash = "sha256:151b3bf73a09f94afc658497cf77d45a565606f62ce0c17acb08cd9937ca206e"}, - {file = "opentelemetry_proto-1.36.0.tar.gz", hash = "sha256:0f10b3c72f74c91e0764a5ec88fd8f1c368ea5d9c64639fb455e2854ef87dd2f"}, -] - -[package.dependencies] -protobuf = ">=5.0,<7.0" - -[[package]] -name = "opentelemetry-sdk" -version = "1.36.0" -description = "OpenTelemetry Python SDK" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_sdk-1.36.0-py3-none-any.whl", hash = "sha256:19fe048b42e98c5c1ffe85b569b7073576ad4ce0bcb6e9b4c6a39e890a6c45fb"}, - {file = "opentelemetry_sdk-1.36.0.tar.gz", hash = "sha256:19c8c81599f51b71670661ff7495c905d8fdf6976e41622d5245b791b06fa581"}, -] - -[package.dependencies] -opentelemetry-api = "1.36.0" -opentelemetry-semantic-conventions = "0.57b0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-semantic-conventions" -version = "0.57b0" -description = "OpenTelemetry Semantic Conventions" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "opentelemetry_semantic_conventions-0.57b0-py3-none-any.whl", hash = "sha256:757f7e76293294f124c827e514c2a3144f191ef175b069ce8d1211e1e38e9e78"}, - {file = "opentelemetry_semantic_conventions-0.57b0.tar.gz", hash = "sha256:609a4a79c7891b4620d64c7aac6898f872d790d75f22019913a660756f27ff32"}, -] - -[package.dependencies] -opentelemetry-api = "1.36.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "orjson" -version = "3.11.1" -description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "orjson-3.11.1-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:92d771c492b64119456afb50f2dff3e03a2db8b5af0eba32c5932d306f970532"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0085ef83a4141c2ed23bfec5fecbfdb1e95dd42fc8e8c76057bdeeec1608ea65"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5caf7f13f2e1b4e137060aed892d4541d07dabc3f29e6d891e2383c7ed483440"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f716bcc166524eddfcf9f13f8209ac19a7f27b05cf591e883419079d98c8c99d"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:507d6012fab05465d8bf21f5d7f4635ba4b6d60132874e349beff12fb51af7fe"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1545083b0931f754c80fd2422a73d83bea7a6d1b6de104a5f2c8dd3d64c291e"}, - {file = "orjson-3.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e217ce3bad76351e1eb29ebe5ca630326f45cd2141f62620107a229909501a3"}, - {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06ef26e009304bda4df42e4afe518994cde6f89b4b04c0ff24021064f83f4fbb"}, - {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:ba49683b87bea3ae1489a88e766e767d4f423a669a61270b6d6a7ead1c33bd65"}, - {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5072488fcc5cbcda2ece966d248e43ea1d222e19dd4c56d3f82747777f24d864"}, - {file = "orjson-3.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f58ae2bcd119226fe4aa934b5880fe57b8e97b69e51d5d91c88a89477a307016"}, - {file = "orjson-3.11.1-cp310-cp310-win32.whl", hash = "sha256:6723be919c07906781b9c63cc52dc7d2fb101336c99dd7e85d3531d73fb493f7"}, - {file = "orjson-3.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:5fd44d69ddfdfb4e8d0d83f09d27a4db34930fba153fbf79f8d4ae8b47914e04"}, - {file = "orjson-3.11.1-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:15e2a57ce3b57c1a36acffcc02e823afefceee0a532180c2568c62213c98e3ef"}, - {file = "orjson-3.11.1-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:17040a83ecaa130474af05bbb59a13cfeb2157d76385556041f945da936b1afd"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a68f23f09e5626cc0867a96cf618f68b91acb4753d33a80bf16111fd7f9928c"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47e07528bb6ccbd6e32a55e330979048b59bfc5518b47c89bc7ab9e3de15174a"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3807cce72bf40a9d251d689cbec28d2efd27e0f6673709f948f971afd52cb09"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b2dc7e88da4ca201c940f5e6127998d9e89aa64264292334dad62854bc7fc27"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3091dad33ac9e67c0a550cfff8ad5be156e2614d6f5d2a9247df0627751a1495"}, - {file = "orjson-3.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ed0fce2307843b79a0c83de49f65b86197f1e2310de07af9db2a1a77a61ce4c"}, - {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a31e84782a18c30abd56774c0cfa7b9884589f4d37d9acabfa0504dad59bb9d"}, - {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:26b6c821abf1ae515fbb8e140a2406c9f9004f3e52acb780b3dee9bfffddbd84"}, - {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f857b3d134b36a8436f1e24dcb525b6b945108b30746c1b0b556200b5cb76d39"}, - {file = "orjson-3.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df146f2a14116ce80f7da669785fcb411406d8e80136558b0ecda4c924b9ac55"}, - {file = "orjson-3.11.1-cp311-cp311-win32.whl", hash = "sha256:d777c57c1f86855fe5492b973f1012be776e0398571f7cc3970e9a58ecf4dc17"}, - {file = "orjson-3.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:e9a5fd589951f02ec2fcb8d69339258bbf74b41b104c556e6d4420ea5e059313"}, - {file = "orjson-3.11.1-cp311-cp311-win_arm64.whl", hash = "sha256:4cddbe41ee04fddad35d75b9cf3e3736ad0b80588280766156b94783167777af"}, - {file = "orjson-3.11.1-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:2b7c8be96db3a977367250c6367793a3c5851a6ca4263f92f0b48d00702f9910"}, - {file = "orjson-3.11.1-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:72e18088f567bd4a45db5e3196677d9ed1605e356e500c8e32dd6e303167a13d"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d346e2ae1ce17888f7040b65a5a4a0c9734cb20ffbd228728661e020b4c8b3a5"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4bda5426ebb02ceb806a7d7ec9ba9ee5e0c93fca62375151a7b1c00bc634d06b"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10506cebe908542c4f024861102673db534fd2e03eb9b95b30d94438fa220abf"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45202ee3f5494644e064c41abd1320497fb92fd31fc73af708708af664ac3b56"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5adaf01b92e0402a9ac5c3ebe04effe2bbb115f0914a0a53d34ea239a746289"}, - {file = "orjson-3.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6162a1a757a1f1f4a94bc6ffac834a3602e04ad5db022dd8395a54ed9dd51c81"}, - {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:78404206977c9f946613d3f916727c189d43193e708d760ea5d4b2087d6b0968"}, - {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:db48f8e81072e26df6cdb0e9fff808c28597c6ac20a13d595756cf9ba1fed48a"}, - {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0c1e394e67ced6bb16fea7054d99fbdd99a539cf4d446d40378d4c06e0a8548d"}, - {file = "orjson-3.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e7a840752c93d4eecd1378e9bb465c3703e127b58f675cd5c620f361b6cf57a4"}, - {file = "orjson-3.11.1-cp312-cp312-win32.whl", hash = "sha256:4537b0e09f45d2b74cb69c7f39ca1e62c24c0488d6bf01cd24673c74cd9596bf"}, - {file = "orjson-3.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:dbee6b050062540ae404530cacec1bf25e56e8d87d8d9b610b935afeb6725cae"}, - {file = "orjson-3.11.1-cp312-cp312-win_arm64.whl", hash = "sha256:f55e557d4248322d87c4673e085c7634039ff04b47bfc823b87149ae12bef60d"}, - {file = "orjson-3.11.1-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53cfefe4af059e65aabe9683f76b9c88bf34b4341a77d329227c2424e0e59b0e"}, - {file = "orjson-3.11.1-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:93d5abed5a6f9e1b6f9b5bf6ed4423c11932b5447c2f7281d3b64e0f26c6d064"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf06642f3db2966df504944cdd0eb68ca2717f0353bb20b20acd78109374a6"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dddf4e78747fa7f2188273f84562017a3c4f0824485b78372513c1681ea7a894"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa3fe8653c9f57f0e16f008e43626485b6723b84b2f741f54d1258095b655912"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6334d2382aff975a61f6f4d1c3daf39368b887c7de08f7c16c58f485dcf7adb2"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3d0855b643f259ee0cb76fe3df4c04483354409a520a902b067c674842eb6b8"}, - {file = "orjson-3.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0eacdfeefd0a79987926476eb16e0245546bedeb8febbbbcf4b653e79257a8e4"}, - {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0ed07faf9e4873518c60480325dcbc16d17c59a165532cccfb409b4cdbaeff24"}, - {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d6d308dd578ae3658f62bb9eba54801533225823cd3248c902be1ebc79b5e014"}, - {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c4aa13ca959ba6b15c0a98d3d204b850f9dc36c08c9ce422ffb024eb30d6e058"}, - {file = "orjson-3.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:be3d0653322abc9b68e5bcdaee6cfd58fcbe9973740ab222b87f4d687232ab1f"}, - {file = "orjson-3.11.1-cp313-cp313-win32.whl", hash = "sha256:4dd34e7e2518de8d7834268846f8cab7204364f427c56fb2251e098da86f5092"}, - {file = "orjson-3.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6895d32032b6362540e6d0694b19130bb4f2ad04694002dce7d8af588ca5f77"}, - {file = "orjson-3.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:bb7c36d5d3570fcbb01d24fa447a21a7fe5a41141fd88e78f7994053cc4e28f4"}, - {file = "orjson-3.11.1-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7b71ef394327b3d0b39f6ea7ade2ecda2731a56c6a7cbf0d6a7301203b92a89b"}, - {file = "orjson-3.11.1-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:77c0fe28ed659b62273995244ae2aa430e432c71f86e4573ab16caa2f2e3ca5e"}, - {file = "orjson-3.11.1-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:1495692f1f1ba2467df429343388a0ed259382835922e124c0cfdd56b3d1f727"}, - {file = "orjson-3.11.1-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:08c6a762fca63ca4dc04f66c48ea5d2428db55839fec996890e1bfaf057b658c"}, - {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e26794fe3976810b2c01fda29bd9ac7c91a3c1284b29cc9a383989f7b614037"}, - {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4b4b4f8f0b1d3ef8dc73e55363a0ffe012a42f4e2f1a140bf559698dca39b3fa"}, - {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:848be553ea35aa89bfefbed2e27c8a41244c862956ab8ba00dc0b27e84fd58de"}, - {file = "orjson-3.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c964c29711a4b1df52f8d9966f015402a6cf87753a406c1c4405c407dd66fd45"}, - {file = "orjson-3.11.1-cp314-cp314-win32.whl", hash = "sha256:33aada2e6b6bc9c540d396528b91e666cedb383740fee6e6a917f561b390ecb1"}, - {file = "orjson-3.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:68e10fd804e44e36188b9952543e3fa22f5aa8394da1b5283ca2b423735c06e8"}, - {file = "orjson-3.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:f3cf6c07f8b32127d836be8e1c55d4f34843f7df346536da768e9f73f22078a1"}, - {file = "orjson-3.11.1-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3d593a9e0bccf2c7401ae53625b519a7ad7aa555b1c82c0042b322762dc8af4e"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0baad413c498fc1eef568504f11ea46bc71f94b845c075e437da1e2b85b4fb86"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:22cf17ae1dae3f9b5f37bfcdba002ed22c98bbdb70306e42dc18d8cc9b50399a"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e855c1e97208133ce88b3ef6663c9a82ddf1d09390cd0856a1638deee0390c3c"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5861c5f7acff10599132854c70ab10abf72aebf7c627ae13575e5f20b1ab8fe"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1e6415c5b5ff3a616a6dafad7b6ec303a9fc625e9313c8e1268fb1370a63dcb"}, - {file = "orjson-3.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:912579642f5d7a4a84d93c5eed8daf0aa34e1f2d3f4dc6571a8e418703f5701e"}, - {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2092e1d3b33f64e129ff8271642afddc43763c81f2c30823b4a4a4a5f2ea5b55"}, - {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:b8ac64caba1add2c04e9cd4782d4d0c4d6c554b7a3369bdec1eed7854c98db7b"}, - {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:23196b826ebc85c43f8e27bee0ab33c5fb13a29ea47fb4fcd6ebb1e660eb0252"}, - {file = "orjson-3.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f2d3364cfad43003f1e3d564a069c8866237cca30f9c914b26ed2740b596ed00"}, - {file = "orjson-3.11.1-cp39-cp39-win32.whl", hash = "sha256:20b0dca94ea4ebe4628330de50975b35817a3f52954c1efb6d5d0498a3bbe581"}, - {file = "orjson-3.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:200c3ad7ed8b5d31d49143265dfebd33420c4b61934ead16833b5cd2c3d241be"}, - {file = "orjson-3.11.1.tar.gz", hash = "sha256:48d82770a5fd88778063604c566f9c7c71820270c9cc9338d25147cbf34afd96"}, -] -markers = {main = "extra == \"langchain\" and platform_python_implementation != \"PyPy\""} - -[[package]] -name = "ormsgpack" -version = "1.10.0" -description = "Fast, correct Python msgpack library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84"}, - {file = "ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07"}, - {file = "ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08"}, - {file = "ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a"}, - {file = "ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0"}, - {file = "ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722"}, - {file = "ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668"}, - {file = "ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69"}, - {file = "ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d"}, - {file = "ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749"}, - {file = "ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16"}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pdoc" -version = "14.7.0" -description = "API Documentation for Python Projects" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "pdoc-14.7.0-py3-none-any.whl", hash = "sha256:72377a907efc6b2c5b3c56b717ef34f11d93621dced3b663f3aede0b844c0ad2"}, - {file = "pdoc-14.7.0.tar.gz", hash = "sha256:2d28af9c0acc39180744ad0543e4bbc3223ecba0d1302db315ec521c51f71f93"}, -] - -[package.dependencies] -Jinja2 = ">=2.11.0" -MarkupSafe = "*" -pygments = ">=2.12.0" - -[package.extras] -dev = ["hypothesis", "mypy", "pdoc-pyo3-sample-library (==1.0.11)", "pygments (>=2.14.0)", "pytest", "pytest-cov", "pytest-timeout", "ruff", "tox", "types-pygments"] - -[[package]] -name = "platformdirs" -version = "4.3.8" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, - {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.14.1)"] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "3.8.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "protobuf" -version = "6.31.1" -description = "" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9"}, - {file = "protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447"}, - {file = "protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6"}, - {file = "protobuf-6.31.1-cp39-cp39-win32.whl", hash = "sha256:0414e3aa5a5f3ff423828e1e6a6e907d6c65c1d5b7e6e975793d5590bdeecc16"}, - {file = "protobuf-6.31.1-cp39-cp39-win_amd64.whl", hash = "sha256:8764cf4587791e7564051b35524b72844f845ad0bb011704c3736cce762d8fe9"}, - {file = "protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e"}, - {file = "protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] -markers = {main = "extra == \"langchain\" and platform_python_implementation == \"PyPy\"", dev = "platform_python_implementation == \"PyPy\""} - -[[package]] -name = "pydantic" -version = "2.11.7" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"}, - {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.33.2" -typing-extensions = ">=4.12.2" -typing-inspection = ">=0.4.0" - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] - -[[package]] -name = "pydantic-core" -version = "2.33.2" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, - {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, - {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, - {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, - {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, - {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, - {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, - {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, - {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, - {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, - {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, - {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, - {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pygments" -version = "2.19.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -groups = ["dev", "docs"] -files = [ - {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, - {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "8.4.1" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"}, - {file = "pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} -iniconfig = ">=1" -packaging = ">=20" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.8" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, -] - -[package.dependencies] -pytest = ">=7.0.0,<9" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - -[[package]] -name = "pytest-httpserver" -version = "1.1.3" -description = "pytest-httpserver is a httpserver for pytest" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pytest_httpserver-1.1.3-py3-none-any.whl", hash = "sha256:5f84757810233e19e2bb5287f3826a71c97a3740abe3a363af9155c0f82fdbb9"}, - {file = "pytest_httpserver-1.1.3.tar.gz", hash = "sha256:af819d6b533f84b4680b9416a5b3f67f1df3701f1da54924afd4d6e4ba5917ec"}, -] - -[package.dependencies] -Werkzeug = ">=2.0.0" - -[[package]] -name = "pytest-timeout" -version = "2.4.0" -description = "pytest plugin to abort hanging tests" -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2"}, - {file = "pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a"}, -] - -[package.dependencies] -pytest = ">=7.0.0" - -[[package]] -name = "pytest-xdist" -version = "3.8.0" -description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"}, - {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"}, -] - -[package.dependencies] -execnet = ">=2.1" -pytest = ">=7.0.0" - -[package.extras] -psutil = ["psutil (>=3.0)"] -setproctitle = ["setproctitle"] -testing = ["filelock"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] -markers = {main = "extra == \"langchain\""} - -[[package]] -name = "regex" -version = "2025.7.34" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d856164d25e2b3b07b779bfed813eb4b6b6ce73c2fd818d46f47c1eb5cd79bd6"}, - {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d15a9da5fad793e35fb7be74eec450d968e05d2e294f3e0e77ab03fa7234a83"}, - {file = "regex-2025.7.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95b4639c77d414efa93c8de14ce3f7965a94d007e068a94f9d4997bb9bd9c81f"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7de1ceed5a5f84f342ba4a9f4ae589524adf9744b2ee61b5da884b5b659834"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02e5860a250cd350c4933cf376c3bc9cb28948e2c96a8bc042aee7b985cfa26f"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a5966220b9a1a88691282b7e4350e9599cf65780ca60d914a798cb791aa1177"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48fb045bbd4aab2418dc1ba2088a5e32de4bfe64e1457b948bb328a8dc2f1c2e"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:20ff8433fa45e131f7316594efe24d4679c5449c0ca69d91c2f9d21846fdf064"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c436fd1e95c04c19039668cfb548450a37c13f051e8659f40aed426e36b3765f"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0b85241d3cfb9f8a13cefdfbd58a2843f208f2ed2c88181bf84e22e0c7fc066d"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:075641c94126b064c65ab86e7e71fc3d63e7ff1bea1fb794f0773c97cdad3a03"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70645cad3407d103d1dbcb4841839d2946f7d36cf38acbd40120fee1682151e5"}, - {file = "regex-2025.7.34-cp310-cp310-win32.whl", hash = "sha256:3b836eb4a95526b263c2a3359308600bd95ce7848ebd3c29af0c37c4f9627cd3"}, - {file = "regex-2025.7.34-cp310-cp310-win_amd64.whl", hash = "sha256:cbfaa401d77334613cf434f723c7e8ba585df162be76474bccc53ae4e5520b3a"}, - {file = "regex-2025.7.34-cp310-cp310-win_arm64.whl", hash = "sha256:bca11d3c38a47c621769433c47f364b44e8043e0de8e482c5968b20ab90a3986"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da304313761b8500b8e175eb2040c4394a875837d5635f6256d6fa0377ad32c8"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:35e43ebf5b18cd751ea81455b19acfdec402e82fe0dc6143edfae4c5c4b3909a"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96bbae4c616726f4661fe7bcad5952e10d25d3c51ddc388189d8864fbc1b3c68"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9feab78a1ffa4f2b1e27b1bcdaad36f48c2fed4870264ce32f52a393db093c78"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f14b36e6d4d07f1a5060f28ef3b3561c5d95eb0651741474ce4c0a4c56ba8719"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85c3a958ef8b3d5079c763477e1f09e89d13ad22198a37e9d7b26b4b17438b33"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37555e4ae0b93358fa7c2d240a4291d4a4227cc7c607d8f85596cdb08ec0a083"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee38926f31f1aa61b0232a3a11b83461f7807661c062df9eb88769d86e6195c3"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a664291c31cae9c4a30589bd8bc2ebb56ef880c9c6264cb7643633831e606a4d"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f3e5c1e0925e77ec46ddc736b756a6da50d4df4ee3f69536ffb2373460e2dafd"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d428fc7731dcbb4e2ffe43aeb8f90775ad155e7db4347a639768bc6cd2df881a"}, - {file = "regex-2025.7.34-cp311-cp311-win32.whl", hash = "sha256:e154a7ee7fa18333ad90b20e16ef84daaeac61877c8ef942ec8dfa50dc38b7a1"}, - {file = "regex-2025.7.34-cp311-cp311-win_amd64.whl", hash = "sha256:24257953d5c1d6d3c129ab03414c07fc1a47833c9165d49b954190b2b7f21a1a"}, - {file = "regex-2025.7.34-cp311-cp311-win_arm64.whl", hash = "sha256:3157aa512b9e606586900888cd469a444f9b898ecb7f8931996cb715f77477f0"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7f7211a746aced993bef487de69307a38c5ddd79257d7be83f7b202cb59ddb50"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fb31080f2bd0681484b275461b202b5ad182f52c9ec606052020fe13eb13a72f"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0200a5150c4cf61e407038f4b4d5cdad13e86345dac29ff9dab3d75d905cf130"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:739a74970e736df0773788377969c9fea3876c2fc13d0563f98e5503e5185f46"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4fef81b2f7ea6a2029161ed6dea9ae13834c28eb5a95b8771828194a026621e4"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea74cf81fe61a7e9d77989050d0089a927ab758c29dac4e8e1b6c06fccf3ebf0"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e4636a7f3b65a5f340ed9ddf53585c42e3ff37101d383ed321bfe5660481744b"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cef962d7834437fe8d3da6f9bfc6f93f20f218266dcefec0560ed7765f5fe01"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:cbe1698e5b80298dbce8df4d8d1182279fbdaf1044e864cbc9d53c20e4a2be77"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:32b9f9bcf0f605eb094b08e8da72e44badabb63dde6b83bd530580b488d1c6da"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:524c868ba527eab4e8744a9287809579f54ae8c62fbf07d62aacd89f6026b282"}, - {file = "regex-2025.7.34-cp312-cp312-win32.whl", hash = "sha256:d600e58ee6d036081c89696d2bdd55d507498a7180df2e19945c6642fac59588"}, - {file = "regex-2025.7.34-cp312-cp312-win_amd64.whl", hash = "sha256:9a9ab52a466a9b4b91564437b36417b76033e8778e5af8f36be835d8cb370d62"}, - {file = "regex-2025.7.34-cp312-cp312-win_arm64.whl", hash = "sha256:c83aec91af9c6fbf7c743274fd952272403ad9a9db05fe9bfc9df8d12b45f176"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c3c9740a77aeef3f5e3aaab92403946a8d34437db930a0280e7e81ddcada61f5"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:69ed3bc611540f2ea70a4080f853741ec698be556b1df404599f8724690edbcd"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d03c6f9dcd562c56527c42b8530aad93193e0b3254a588be1f2ed378cdfdea1b"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6164b1d99dee1dfad33f301f174d8139d4368a9fb50bf0a3603b2eaf579963ad"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1e4f4f62599b8142362f164ce776f19d79bdd21273e86920a7b604a4275b4f59"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72a26dcc6a59c057b292f39d41465d8233a10fd69121fa24f8f43ec6294e5415"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5273fddf7a3e602695c92716c420c377599ed3c853ea669c1fe26218867002f"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c1844be23cd40135b3a5a4dd298e1e0c0cb36757364dd6cdc6025770363e06c1"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dde35e2afbbe2272f8abee3b9fe6772d9b5a07d82607b5788e8508974059925c"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f6e8e7af516a7549412ce57613e859c3be27d55341a894aacaa11703a4c31a"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:469142fb94a869beb25b5f18ea87646d21def10fbacb0bcb749224f3509476f0"}, - {file = "regex-2025.7.34-cp313-cp313-win32.whl", hash = "sha256:da7507d083ee33ccea1310447410c27ca11fb9ef18c95899ca57ff60a7e4d8f1"}, - {file = "regex-2025.7.34-cp313-cp313-win_amd64.whl", hash = "sha256:9d644de5520441e5f7e2db63aec2748948cc39ed4d7a87fd5db578ea4043d997"}, - {file = "regex-2025.7.34-cp313-cp313-win_arm64.whl", hash = "sha256:7bf1c5503a9f2cbd2f52d7e260acb3131b07b6273c470abb78568174fe6bde3f"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:8283afe7042d8270cecf27cca558873168e771183d4d593e3c5fe5f12402212a"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6c053f9647e3421dd2f5dff8172eb7b4eec129df9d1d2f7133a4386319b47435"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a16dd56bbcb7d10e62861c3cd000290ddff28ea142ffb5eb3470f183628011ac"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69c593ff5a24c0d5c1112b0df9b09eae42b33c014bdca7022d6523b210b69f72"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98d0ce170fcde1a03b5df19c5650db22ab58af375aaa6ff07978a85c9f250f0e"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d72765a4bff8c43711d5b0f5b452991a9947853dfa471972169b3cc0ba1d0751"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4494f8fd95a77eb434039ad8460e64d57baa0434f1395b7da44015bef650d0e4"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4f42b522259c66e918a0121a12429b2abcf696c6f967fa37bdc7b72e61469f98"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:aaef1f056d96a0a5d53ad47d019d5b4c66fe4be2da87016e0d43b7242599ffc7"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:656433e5b7dccc9bc0da6312da8eb897b81f5e560321ec413500e5367fcd5d47"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e91eb2c62c39705e17b4d42d4b86c4e86c884c0d15d9c5a47d0835f8387add8e"}, - {file = "regex-2025.7.34-cp314-cp314-win32.whl", hash = "sha256:f978ddfb6216028c8f1d6b0f7ef779949498b64117fc35a939022f67f810bdcb"}, - {file = "regex-2025.7.34-cp314-cp314-win_amd64.whl", hash = "sha256:4b7dc33b9b48fb37ead12ffc7bdb846ac72f99a80373c4da48f64b373a7abeae"}, - {file = "regex-2025.7.34-cp314-cp314-win_arm64.whl", hash = "sha256:4b8c4d39f451e64809912c82392933d80fe2e4a87eeef8859fcc5380d0173c64"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd5edc3f453de727af267c7909d083e19f6426fc9dd149e332b6034f2a5611e6"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa1cdfb8db96ef20137de5587954c812821966c3e8b48ffc871e22d7ec0a4938"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89c9504fc96268e8e74b0283e548f53a80c421182a2007e3365805b74ceef936"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33be70d75fa05a904ee0dc43b650844e067d14c849df7e82ad673541cd465b5f"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57d25b6732ea93eeb1d090e8399b6235ca84a651b52d52d272ed37d3d2efa0f1"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:baf2fe122a3db1c0b9f161aa44463d8f7e33eeeda47bb0309923deb743a18276"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a764a83128af9c1a54be81485b34dca488cbcacefe1e1d543ef11fbace191e1"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7f663ccc4093877f55b51477522abd7299a14c5bb7626c5238599db6a0cb95d"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4913f52fbc7a744aaebf53acd8d3dc1b519e46ba481d4d7596de3c862e011ada"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:efac4db9e044d47fd3b6b0d40b6708f4dfa2d8131a5ac1d604064147c0f552fd"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7373afae7cfb716e3b8e15d0184510d518f9d21471f2d62918dbece85f2c588f"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9960d162f3fecf6af252534a1ae337e9c2e20d74469fed782903b24e2cc9d3d7"}, - {file = "regex-2025.7.34-cp39-cp39-win32.whl", hash = "sha256:95d538b10eb4621350a54bf14600cc80b514211d91a019dc74b8e23d2159ace5"}, - {file = "regex-2025.7.34-cp39-cp39-win_amd64.whl", hash = "sha256:f7f3071b5faa605b0ea51ec4bb3ea7257277446b053f4fd3ad02b1dcb4e64353"}, - {file = "regex-2025.7.34-cp39-cp39-win_arm64.whl", hash = "sha256:716a47515ba1d03f8e8a61c5013041c8c90f2e21f055203498105d7571b44531"}, - {file = "regex-2025.7.34.tar.gz", hash = "sha256:9ead9765217afd04a86822dfcd4ed2747dfe426e887da413b15ff0ac2457e21a"}, -] - -[[package]] -name = "requests" -version = "2.32.4" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, - {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main", "dev"] -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] -markers = {main = "extra == \"langchain\""} - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "ruff" -version = "0.5.7" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -groups = ["dev"] -files = [ - {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, - {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, - {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, - {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, - {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, - {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, - {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.42" -description = "Database Abstraction Library" -optional = true -python-versions = ">=3.7" -groups = ["main"] -markers = "extra == \"langchain\"" -files = [ - {file = "SQLAlchemy-2.0.42-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7ee065898359fdee83961aed5cf1fb4cfa913ba71b58b41e036001d90bebbf7a"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56bc76d86216443daa2e27e6b04a9b96423f0b69b5d0c40c7f4b9a4cdf7d8d90"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89143290fb94c50a8dec73b06109ccd245efd8011d24fc0ddafe89dc55b36651"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:4efbdc9754c7145a954911bfeef815fb0843e8edab0e9cecfa3417a5cbd316af"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:88f8a8007a658dfd82c16a20bd9673ae6b33576c003b5166d42697d49e496e61"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-win32.whl", hash = "sha256:c5dd245e6502990ccf612d51f220a7b04cbea3f00f6030691ffe27def76ca79b"}, - {file = "SQLAlchemy-2.0.42-cp37-cp37m-win_amd64.whl", hash = "sha256:5651eb19cacbeb2fe7431e4019312ed00a0b3fbd2d701423e0e2ceaadb5bcd9f"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:172b244753e034d91a826f80a9a70f4cbac690641207f2217f8404c261473efe"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be28f88abd74af8519a4542185ee80ca914933ca65cdfa99504d82af0e4210df"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98b344859d282fde388047f1710860bb23f4098f705491e06b8ab52a48aafea9"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97978d223b11f1d161390a96f28c49a13ce48fdd2fed7683167c39bdb1b8aa09"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e35b9b000c59fcac2867ab3a79fc368a6caca8706741beab3b799d47005b3407"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bc7347ad7a7b1c78b94177f2d57263113bb950e62c59b96ed839b131ea4234e1"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-win32.whl", hash = "sha256:739e58879b20a179156b63aa21f05ccacfd3e28e08e9c2b630ff55cd7177c4f1"}, - {file = "sqlalchemy-2.0.42-cp310-cp310-win_amd64.whl", hash = "sha256:1aef304ada61b81f1955196f584b9e72b798ed525a7c0b46e09e98397393297b"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c34100c0b7ea31fbc113c124bcf93a53094f8951c7bf39c45f39d327bad6d1e7"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ad59dbe4d1252448c19d171dfba14c74e7950b46dc49d015722a4a06bfdab2b0"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9187498c2149919753a7fd51766ea9c8eecdec7da47c1b955fa8090bc642eaa"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f092cf83ebcafba23a247f5e03f99f5436e3ef026d01c8213b5eca48ad6efa9"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc6afee7e66fdba4f5a68610b487c1f754fccdc53894a9567785932dbb6a265e"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:260ca1d2e5910f1f1ad3fe0113f8fab28657cee2542cb48c2f342ed90046e8ec"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-win32.whl", hash = "sha256:2eb539fd83185a85e5fcd6b19214e1c734ab0351d81505b0f987705ba0a1e231"}, - {file = "sqlalchemy-2.0.42-cp311-cp311-win_amd64.whl", hash = "sha256:9193fa484bf00dcc1804aecbb4f528f1123c04bad6a08d7710c909750fa76aeb"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:09637a0872689d3eb71c41e249c6f422e3e18bbd05b4cd258193cfc7a9a50da2"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a3cb3ec67cc08bea54e06b569398ae21623534a7b1b23c258883a7c696ae10df"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e87e6a5ef6f9d8daeb2ce5918bf5fddecc11cae6a7d7a671fcc4616c47635e01"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b718011a9d66c0d2f78e1997755cd965f3414563b31867475e9bc6efdc2281d"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:16d9b544873fe6486dddbb859501a07d89f77c61d29060bb87d0faf7519b6a4d"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:21bfdf57abf72fa89b97dd74d3187caa3172a78c125f2144764a73970810c4ee"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-win32.whl", hash = "sha256:78b46555b730a24901ceb4cb901c6b45c9407f8875209ed3c5d6bcd0390a6ed1"}, - {file = "sqlalchemy-2.0.42-cp312-cp312-win_amd64.whl", hash = "sha256:4c94447a016f36c4da80072e6c6964713b0af3c8019e9c4daadf21f61b81ab53"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:941804f55c7d507334da38133268e3f6e5b0340d584ba0f277dd884197f4ae8c"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d3d06a968a760ce2aa6a5889fefcbdd53ca935735e0768e1db046ec08cbf01"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cf10396a8a700a0f38ccd220d940be529c8f64435c5d5b29375acab9267a6c9"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cae6c2b05326d7c2c7c0519f323f90e0fb9e8afa783c6a05bb9ee92a90d0f04"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f50f7b20677b23cfb35b6afcd8372b2feb348a38e3033f6447ee0704540be894"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d88a1c0d66d24e229e3938e1ef16ebdbd2bf4ced93af6eff55225f7465cf350"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-win32.whl", hash = "sha256:45c842c94c9ad546c72225a0c0d1ae8ef3f7c212484be3d429715a062970e87f"}, - {file = "sqlalchemy-2.0.42-cp313-cp313-win_amd64.whl", hash = "sha256:eb9905f7f1e49fd57a7ed6269bc567fcbbdac9feadff20ad6bd7707266a91577"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ed5a6959b1668d97a32e3fd848b485f65ee3c05a759dee06d90e4545a3c77f1e"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2ddbaafe32f0dd12d64284b1c3189104b784c9f3dba8cc1ba7e642e2b14b906f"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37f4f42568b6c656ee177b3e111d354b5dda75eafe9fe63492535f91dfa35829"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb57923d852d38671a17abda9a65cc59e3e5eab51fb8307b09de46ed775bcbb8"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:437c2a8b0c780ff8168a470beb22cb4a25e1c63ea6a7aec87ffeb07aa4b76641"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:480f7df62f0b3ad6aa011eefa096049dc1770208bb71f234959ee2864206eefe"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-win32.whl", hash = "sha256:d119c80c614d62d32e236ae68e21dd28a2eaf070876b2f28a6075d5bae54ef3f"}, - {file = "sqlalchemy-2.0.42-cp38-cp38-win_amd64.whl", hash = "sha256:be3a02f963c8d66e28bb4183bebab66dc4379701d92e660f461c65fecd6ff399"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:78548fd65cd76d4c5a2e6b5f245d7734023ee4de33ee7bb298f1ac25a9935e0d"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf4bf5a174d8a679a713b7a896470ffc6baab78e80a79e7ec5668387ffeccc8b"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c7ff7ba08b375f8a8fa0511e595c9bdabb5494ec68f1cf69bb24e54c0d90f2"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b3c117f65d64e806ce5ce9ce578f06224dc36845e25ebd2554b3e86960e1aed"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:27e4a7b3a7a61ff919c2e7caafd612f8626114e6e5ebbe339de3b5b1df9bc27e"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b01e0dd39f96aefda5ab002d8402db4895db871eb0145836246ce0661635ce55"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-win32.whl", hash = "sha256:49362193b1f43aa158deebf438062d7b5495daa9177c6c5d0f02ceeb64b544ea"}, - {file = "sqlalchemy-2.0.42-cp39-cp39-win_amd64.whl", hash = "sha256:636ec3dc83b2422a7ff548d0f8abf9c23742ca50e2a5cdc492a151eac7a0248b"}, - {file = "sqlalchemy-2.0.42-py3-none-any.whl", hash = "sha256:defcdff7e661f0043daa381832af65d616e060ddb54d3fe4476f51df7eaa1835"}, - {file = "sqlalchemy-2.0.42.tar.gz", hash = "sha256:160bedd8a5c28765bd5be4dec2d881e109e33b34922e50a3b881a7681773ac5f"}, -] - -[package.dependencies] -greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} -typing-extensions = ">=4.6.0" - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] -aioodbc = ["aioodbc", "greenlet (>=1)"] -aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (>=1)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "tenacity" -version = "9.1.2" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, - {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, -] -markers = {main = "extra == \"langchain\""} - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "tiktoken" -version = "0.10.0" -description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "tiktoken-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1db7a65b196d757d18ef53193957d44549b88f373d4b87db532f04d18193b847"}, - {file = "tiktoken-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f55701461267d025597ebb2290d612fe9c5c5fbb625ebf7495c9f0f8e4c30f01"}, - {file = "tiktoken-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f83693279af9e8deac0363cbf21dc3d666807f22dcc1091f51e69e6fe6433f71"}, - {file = "tiktoken-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f973bdeb68d645f73dcce60c7795cb5c6f8b7f3dcf92c40c39ad4aee398c075"}, - {file = "tiktoken-0.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d5cab2a8e8974d6c9744264e94886a58b9087a39737c53fd65dbe2fe8522e719"}, - {file = "tiktoken-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:7a49d2aedf911b68f23c9c84abce8eaf569cb02613f307cee4fb1bebd8c55ae9"}, - {file = "tiktoken-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:29f55c6b7c9a6a7ea953691c3962ee8fe4ee2f0ceb2a3fded3925acfc45e4b0a"}, - {file = "tiktoken-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f641d0735059b48252c4409d6546b6a62edeb4c4e48306499db11bbe403b872f"}, - {file = "tiktoken-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad76e03676b36c2a5e5304b428cff48eb86a033af55212d41a6ac6faec25b2ad"}, - {file = "tiktoken-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6420ecbd4dc4db3b82ca3421f50d1207d750de1a2856e6ca0544294fe58d2853"}, - {file = "tiktoken-0.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d2e032cd44700a9ed511c50b9f302bb9e9e77e2ebf8e2d9b8ec12ce64ebf00c6"}, - {file = "tiktoken-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:eb520960fa1788caf033489e3b63bb675c0f321db40569b2d3ca24d7fab5ca72"}, - {file = "tiktoken-0.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:25c27021a605b2778af07f84a33fe7c74b5c960a8cfac5d2a7a1075ed592cbe4"}, - {file = "tiktoken-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:45d654f049b4f7ed617ad0c66462c15cc41e5db120f37f122d5b57ffa2aec062"}, - {file = "tiktoken-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34f73d93641b9cc73e19b18dbf9ce1baf086f1c4e18cfa36b952956843bca23c"}, - {file = "tiktoken-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fbfc5dda624c0f85c56bbf8f2ffb42964c798fc6fc1c321a452bf31d4ba21f5"}, - {file = "tiktoken-0.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:853671af10636b581d632fe7b64b755301c73bc1f2ce837a8cdd9a44ab51f846"}, - {file = "tiktoken-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:56c4e7544be63c78265c82857b9f2a4e2190ae29541fe3467708fc7aabcb1522"}, - {file = "tiktoken-0.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:10e779827ddb0490a415d09d95f8e7a982fd8e14f88c4c2348358f722af3c415"}, - {file = "tiktoken-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:783892cdbec0d33f0f51373d8969e059ab1244af531a52338f702131a032a116"}, - {file = "tiktoken-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43f38d62b6a62a7c82be3770fcdc24cdf5bff3bdf718909d038b804ac774a025"}, - {file = "tiktoken-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72d0b30e08f1e856fa76ee423a3d3f0b1bc984cb6e86a21dbd7c5eee8f67f8f5"}, - {file = "tiktoken-0.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa840eba09a0c1db0b436baf6cfe1ab7906f33fb663cf96f772a818bad5856a6"}, - {file = "tiktoken-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:642b8d9f266004629ea2457aa29a9eed4f1a031fd804f8c489edbf32df7026c3"}, - {file = "tiktoken-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:28fcb8555bb3e9cc6d625385b688b9781e7eb022e76826e721ad93198920034b"}, - {file = "tiktoken-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b8e20f7da9086cb5b88eb53ef7ee2fd2db9f3b55c0bcddad51d1ad001a6fcf07"}, - {file = "tiktoken-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f795e7c451d560142c2d88d239ae9fcc11f0b4647376db625c9d4be8f16da45"}, - {file = "tiktoken-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8b3a5717679abb3e8a2097d9577e4c69b975c7fc0381d42598fa6f36f040fc3"}, - {file = "tiktoken-0.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b061e5035a561a18aefcd969079f1952b4caee3bb204ecfadb4bb41b81b8331b"}, - {file = "tiktoken-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a08250ef9b688c84a7f013fee01d587e73aaf41839bcd564105535276c55122b"}, - {file = "tiktoken-0.10.0.tar.gz", hash = "sha256:7cd88c11699b18081822e6ae1beee55e8f20ea361d73c507d33f5a89a1898f1c"}, -] - -[package.dependencies] -regex = ">=2022.1.18" -requests = ">=2.26.0" - -[package.extras] -blobfile = ["blobfile (>=2)"] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -markers = "python_version < \"3.11\"" -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[[package]] -name = "tqdm" -version = "4.67.1" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -groups = ["main", "dev"] -files = [ - {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, - {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, -] -markers = {main = "extra == \"openai\""} - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] -discord = ["requests"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.14.1" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, - {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, -] - -[[package]] -name = "typing-inspection" -version = "0.4.1" -description = "Runtime typing introspection tools" -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"}, - {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"}, -] - -[package.dependencies] -typing-extensions = ">=4.12.0" - -[[package]] -name = "urllib3" -version = "2.5.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -groups = ["main", "dev"] -files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "virtualenv" -version = "20.33.1" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.8" -groups = ["dev"] -files = [ - {file = "virtualenv-20.33.1-py3-none-any.whl", hash = "sha256:07c19bc66c11acab6a5958b815cbcee30891cd1c2ccf53785a28651a0d8d8a67"}, - {file = "virtualenv-20.33.1.tar.gz", hash = "sha256:1b44478d9e261b3fb8baa5e74a0ca3bc0e05f21aa36167bf9cbf850e542765b8"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""] - -[[package]] -name = "werkzeug" -version = "3.1.3" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.9" -groups = ["dev"] -files = [ - {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, - {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, -] - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog (>=2.3)"] - -[[package]] -name = "wrapt" -version = "1.17.2" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.8" -groups = ["main"] -files = [ - {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, - {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, - {file = "wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7"}, - {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c"}, - {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72"}, - {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061"}, - {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2"}, - {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c"}, - {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62"}, - {file = "wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563"}, - {file = "wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f"}, - {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"}, - {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda"}, - {file = "wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72"}, - {file = "wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317"}, - {file = "wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, - {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, - {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, - {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125"}, - {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998"}, - {file = "wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5"}, - {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8"}, - {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6"}, - {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc"}, - {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2"}, - {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b"}, - {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504"}, - {file = "wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a"}, - {file = "wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845"}, - {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192"}, - {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b"}, - {file = "wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0"}, - {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306"}, - {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb"}, - {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681"}, - {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6"}, - {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6"}, - {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f"}, - {file = "wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555"}, - {file = "wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c"}, - {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9"}, - {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119"}, - {file = "wrapt-1.17.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6"}, - {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9"}, - {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a"}, - {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2"}, - {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a"}, - {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04"}, - {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f"}, - {file = "wrapt-1.17.2-cp38-cp38-win32.whl", hash = "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7"}, - {file = "wrapt-1.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3"}, - {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a"}, - {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061"}, - {file = "wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82"}, - {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9"}, - {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f"}, - {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b"}, - {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f"}, - {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8"}, - {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9"}, - {file = "wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb"}, - {file = "wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb"}, - {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, - {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, -] - -[[package]] -name = "zipp" -version = "3.23.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.9" -groups = ["main"] -files = [ - {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, - {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - -[[package]] -name = "zstandard" -version = "0.23.0" -description = "Zstandard bindings for Python" -optional = false -python-versions = ">=3.8" -groups = ["main", "dev"] -files = [ - {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, - {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c"}, - {file = "zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813"}, - {file = "zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4"}, - {file = "zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e"}, - {file = "zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473"}, - {file = "zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160"}, - {file = "zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0"}, - {file = "zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094"}, - {file = "zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35"}, - {file = "zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d"}, - {file = "zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b"}, - {file = "zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9"}, - {file = "zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33"}, - {file = "zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd"}, - {file = "zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b"}, - {file = "zstandard-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc"}, - {file = "zstandard-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e"}, - {file = "zstandard-0.23.0-cp38-cp38-win32.whl", hash = "sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9"}, - {file = "zstandard-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f"}, - {file = "zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb"}, - {file = "zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5"}, - {file = "zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274"}, - {file = "zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58"}, - {file = "zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09"}, -] -markers = {main = "extra == \"langchain\""} - -[package.dependencies] -cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\""} - -[package.extras] -cffi = ["cffi (>=1.11)"] - -[extras] -langchain = ["langchain"] -openai = ["openai"] - -[metadata] -lock-version = "2.1" -python-versions = ">=3.9,<4.0" -content-hash = "746d378f1bbcf8c86346a0ac7a4ebb400462d38e43eee5d7edf51dd78a8307a1" From abd14debbf81f0a32135b2daeef7664bd3c896a3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 13:25:52 +0200 Subject: [PATCH 16/66] update --- langfuse/_client/constants.py | 42 ++++++++++- langfuse/_client/observe.py | 87 ++++------------------ langfuse/_client/span.py | 3 + tests/test_manual_graph_instrumentation.py | 2 +- 4 files changed, 60 insertions(+), 74 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 97517865f..e7563c98e 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -3,9 +3,32 @@ This module defines constants used throughout the Langfuse OpenTelemetry integration. """ +import enum +from typing import Literal +from typing_extensions import TypeAlias + LANGFUSE_TRACER_NAME = "langfuse-sdk" -# Valid observation types for the @observe decorator + +class ObservationType(str, enum.Enum): + """Enumeration of valid observation types for Langfuse tracing. + + This enum defines all the observation types that can be used with the @observe + decorator and other Langfuse SDK methods. + """ + + SPAN = "SPAN" + GENERATION = "GENERATION" + AGENT = "AGENT" + TOOL = "TOOL" + CHAIN = "CHAIN" + RETRIEVER = "RETRIEVER" + EMBEDDING = "EMBEDDING" + EVALUATOR = "EVALUATOR" + GUARDRAIL = "GUARDRAIL" + + +# Valid observation types for the @observe decorator (lowercase user interface) VALID_OBSERVATION_TYPES = { "span", "event", @@ -14,5 +37,22 @@ "tool", "chain", "retriever", + "evaluator", "embedding", + "guardrail", } + +ObservationTypeLiteralNoEvent: TypeAlias = Literal[ + "span", + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + "guardrail", +] + +ObservationTypeLiteral: TypeAlias = ObservationTypeLiteralNoEvent | Literal["event"] +] diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 52ee25485..323290ac8 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -10,7 +10,6 @@ Dict, Generator, Iterable, - Literal, Optional, Tuple, TypeVar, @@ -26,7 +25,7 @@ LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, ) -from langfuse._client.constants import VALID_OBSERVATION_TYPES +from langfuse._client.constants import VALID_OBSERVATION_TYPES, ObservationTypeLiteralNoEvent from langfuse._client.get_client import _set_current_public_key, get_client from langfuse._client.span import LangfuseGeneration, LangfuseSpan from langfuse.types import TraceContext @@ -67,19 +66,7 @@ def observe( func: None = None, *, name: Optional[str] = None, - as_type: Optional[Literal["generation"]] = None, - type: Optional[ - Literal[ - "span", - "event", - "generation", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ] = None, + as_type: Optional[ObservationTypeLiteralNoEvent] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -90,19 +77,7 @@ def observe( func: Optional[F] = None, *, name: Optional[str] = None, - as_type: Optional[Literal["generation"]] = None, - type: Optional[ - Literal[ - "span", - "event", - "generation", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ] = None, + as_type: Optional[ObservationTypeLiteralNoEvent] = None, capture_input: Optional[bool] = None, capture_output: Optional[bool] = None, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -119,11 +94,10 @@ def observe( Args: func (Optional[Callable]): The function to decorate. When used with parentheses @observe(), this will be None. name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used. - as_type (Optional[Literal["generation"]]): Set to "generation" to create a specialized LLM generation span - with model metrics support, suitable for tracking language model outputs. - type (Optional[Literal]): Set the observation type for agentic workflows. Supported values: - "generation", "agent", "tool", "chain", "retriever", "embedding". When specified, creates spans with - the specified type for graph visualization and filtering in the Langfuse UI. + as_type (Optional[Literal]): Set the observation type. Supported values: + "generation", "span", "agent", "tool", "chain", "retriever", "embedding", "evaluator", "guardrail". + When set to "generation", creates a specialized LLM generation span with model metrics support. + Other types create spans with the specified type for graph visualization and filtering in the Langfuse UI. Returns: Callable: A wrapped version of the original function that automatically creates and manages Langfuse spans. @@ -151,7 +125,7 @@ async def generate_answer(query): For automatic graph instrumentation with agent workflows: ```python - @observe(type="agent") + @observe(as_type="agent") def planning_agent(): return create_plan() ``` @@ -182,18 +156,11 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ - if as_type is not None and type is not None: - raise ValueError( - "Cannot specify both 'as_type' and 'type' parameters. Please use only one of them." - ) - if type is not None and type not in VALID_OBSERVATION_TYPES: - raise ValueError( - f"Invalid observation type '{type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" - ) if as_type is not None and as_type not in VALID_OBSERVATION_TYPES: - raise ValueError( - f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}" + self._log.warning( + f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}. Defaulting to 'span'." ) + as_type = "span" function_io_capture_enabled = os.environ.get( LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, "True" @@ -210,14 +177,12 @@ def sub_process(): ) def decorator(func: F) -> F: - # TODO: merge smartly with manually set as_type - consolidated_type = type or as_type return ( self._async_observe( func, name=name, - as_type=consolidated_type, + as_type=as_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -226,7 +191,7 @@ def decorator(func: F) -> F: else self._sync_observe( func, name=name, - as_type=consolidated_type, + as_type=as_type, capture_input=should_capture_input, capture_output=should_capture_output, transform_to_string=transform_to_string, @@ -253,18 +218,7 @@ def _async_observe( func: F, *, name: Optional[str], - as_type: Optional[ - Literal[ - "span", - "generation", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ], + as_type: Optional[ObservationTypeLiteralNoEvent], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, @@ -373,18 +327,7 @@ def _sync_observe( func: F, *, name: Optional[str], - as_type: Optional[ - Literal[ - "span", - "generation", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ], + as_type: Optional[ObservationTypeLiteralNoEvent], capture_input: bool, capture_output: bool, transform_to_string: Optional[Callable[[Iterable], str]] = None, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index c550eeab3..1b6ab7a2f 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -109,6 +109,9 @@ def __init__( prompt: Associated prompt template from Langfuse prompt management """ self._otel_span = otel_span + self._otel_span.set_attribute( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE, as_type + ) self._langfuse_client = langfuse_client self.trace_id = self._langfuse_client._get_otel_trace_id(otel_span) diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index d63090e87..5b73662fb 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -5,7 +5,7 @@ def test_observe_type_agent_instrumentation(): - """Test @observe(type='agent') with the type-based approach.""" + """Test @observe(as_type='agent') with the as_type-based approach.""" langfuse = Langfuse() api = get_api() From 53a9bff2186f860319e9de981cefdd87fd3f46b8 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 13:31:02 +0200 Subject: [PATCH 17/66] update --- langfuse/__init__.py | 17 ++++++++- langfuse/_client/client.py | 71 +++++++++++++---------------------- langfuse/_client/constants.py | 1 - langfuse/_client/span.py | 20 +++++++++- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/langfuse/__init__.py b/langfuse/__init__.py index 3359f9d18..3449e851f 100644 --- a/langfuse/__init__.py +++ b/langfuse/__init__.py @@ -2,9 +2,21 @@ from ._client import client as _client_module from ._client.attributes import LangfuseOtelSpanAttributes +from ._client.constants import ObservationTypeLiteral from ._client.get_client import get_client from ._client.observe import observe -from ._client.span import LangfuseEvent, LangfuseGeneration, LangfuseSpan, LangfuseAgent, LangfuseTool, LangfuseChain, LangfuseEmbedding, LangfuseRetriever +from ._client.span import ( + LangfuseEvent, + LangfuseGeneration, + LangfuseSpan, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseEmbedding, + LangfuseEvaluator, + LangfuseRetriever, + LangfuseGuardrail, +) Langfuse = _client_module.Langfuse @@ -12,6 +24,7 @@ "Langfuse", "get_client", "observe", + "ObservationTypeLiteral", "LangfuseSpan", "LangfuseGeneration", "LangfuseEvent", @@ -20,5 +33,7 @@ "LangfuseTool", "LangfuseChain", "LangfuseEmbedding", + "LangfuseEvaluator", "LangfuseRetriever", + "LangfuseGuardrail", ] diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 511e84c76..1d0f95314 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -36,6 +36,7 @@ LANGFUSE_TRACING_ENABLED, LANGFUSE_TRACING_ENVIRONMENT, ) +from langfuse._client.constants import ObservationTypeLiteral, ObservationTypeLiteralNoEvent from langfuse._client.resource_manager import LangfuseResourceManager from langfuse._client.span import ( LangfuseEvent, @@ -45,7 +46,9 @@ LangfuseTool, LangfuseChain, LangfuseRetriever, + LangfuseEvaluator, LangfuseEmbedding, + LangfuseGuardrail, ) from langfuse._utils import _get_timestamp from langfuse._utils.parse_error import handle_fern_exception @@ -355,18 +358,6 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - as_type: Optional[ - Literal[ - "generation", - "span", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ] = None, ) -> _AgnosticContextManager[LangfuseSpan]: """Create a new span and set it as the current span in a context manager. @@ -685,33 +676,33 @@ def start_as_current_generation( def _get_span_class( self, - as_type: Literal[ - "span", - "generation", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ], + as_type: ObservationTypeLiteral, ) -> type: """Get the appropriate span class based on as_type.""" - if as_type == "agent": + normalized_type = as_type.upper() + + if normalized_type == "AGENT": return LangfuseAgent - elif as_type == "tool": + elif normalized_type == "TOOL": return LangfuseTool - elif as_type == "chain": + elif normalized_type == "CHAIN": return LangfuseChain - elif as_type == "retriever": + elif normalized_type == "RETRIEVER": return LangfuseRetriever - elif as_type == "embedding": + elif normalized_type == "EVALUATOR": + return LangfuseEvaluator + elif normalized_type == "EMBEDDING": return LangfuseEmbedding - elif as_type == "generation": + elif normalized_type == "GUARDRAIL": + return LangfuseGuardrail + elif normalized_type == "GENERATION": return LangfuseGeneration - elif as_type == "event": + elif normalized_type == "EVENT": return LangfuseEvent - elif as_type == "span": + elif normalized_type == "SPAN": + return LangfuseSpan + else: + # Default to LangfuseSpan for unrecognized types return LangfuseSpan @_agnosticcontextmanager @@ -721,7 +712,7 @@ def _create_span_with_parent_context( name: str, parent: Optional[otel_trace_api.Span] = None, remote_parent_span: Optional[otel_trace_api.Span] = None, - as_type: Literal["generation", "span", "agent", "tool", "chain", "retriever"], + as_type: ObservationTypeLiteralNoEvent, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -768,18 +759,7 @@ def _start_as_current_otel_span_with_processed_media( self, *, name: str, - as_type: Optional[ - Literal[ - "generation", - "span", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ] = None, + as_type: Optional[ObservationTypeLiteralNoEvent] = None, end_on_exit: Optional[bool] = None, input: Optional[Any] = None, output: Optional[Any] = None, @@ -798,7 +778,7 @@ def _start_as_current_otel_span_with_processed_media( name=name, end_on_exit=end_on_exit if end_on_exit is not None else True, ) as otel_span: - span_class = self._get_span_class(as_type or "generation") + span_class = self._get_span_class(as_type or "generation") # default was "generation" common_args = { "otel_span": otel_span, "langfuse_client": self, @@ -822,13 +802,16 @@ def _start_as_current_otel_span_with_processed_media( "prompt": prompt, } ) + # TODO: for some, create generation-like classes with those props. elif span_class in [ LangfuseSpan, LangfuseAgent, LangfuseTool, LangfuseChain, LangfuseRetriever, + LangfuseEvaluator, LangfuseEmbedding, + LangfuseGuardrail, ]: # set their type internally in the class pass diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index e7563c98e..2e32bbb58 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -55,4 +55,3 @@ class ObservationType(str, enum.Enum): ] ObservationTypeLiteral: TypeAlias = ObservationTypeLiteralNoEvent | Literal["event"] -] diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 1b6ab7a2f..1308f60c7 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1374,5 +1374,23 @@ class LangfuseEmbedding(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEmbedding span.""" - kwargs["observation_type"] = "embedding" + kwargs["observation_type"] = "EMBEDDING" + super().__init__(**kwargs) + + +class LangfuseEvaluator(LangfuseGraphObservation): + """Specialized span for evaluator observations in agentic workflows.""" + + def __init__(self, **kwargs: Any) -> None: + """Initialize a new LangfuseEvaluator span.""" + kwargs["observation_type"] = "EVALUATOR" + super().__init__(**kwargs) + + +class LangfuseGuardrail(LangfuseGraphObservation): + """Specialized span for guardrail observations in agentic workflows.""" + + def __init__(self, **kwargs: Any) -> None: + """Initialize a new LangfuseGuardrail span.""" + kwargs["observation_type"] = "GUARDRAIL" super().__init__(**kwargs) From 180cb96ebd50038305882999d4128d62df472327 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:03:11 +0200 Subject: [PATCH 18/66] fix cases --- langfuse/_client/client.py | 325 ++++++++++++++++++++++++++++++++++-- langfuse/_client/observe.py | 78 +++++---- langfuse/_client/span.py | 35 +--- 3 files changed, 363 insertions(+), 75 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 1d0f95314..e87b8ef9d 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -36,7 +36,10 @@ LANGFUSE_TRACING_ENABLED, LANGFUSE_TRACING_ENVIRONMENT, ) -from langfuse._client.constants import ObservationTypeLiteral, ObservationTypeLiteralNoEvent +from langfuse._client.constants import ( + ObservationTypeLiteral, + ObservationTypeLiteralNoEvent, +) from langfuse._client.resource_manager import LangfuseResourceManager from langfuse._client.span import ( LangfuseEvent, @@ -674,32 +677,326 @@ def start_as_current_generation( ), ) + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["generation"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseGeneration]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["span"] = "span", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseSpan]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal[ + "agent", "tool", "chain", "retriever", "evaluator", "embedding", "guardrail" + ], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[ + Union[ + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ]: ... + + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: ObservationTypeLiteralNoEvent = "span", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ]: + """Create a new observation and set it as the current span in a context manager. + + This method creates a new observation of the specified type and sets it as the + current span within a context manager. Use this method with a 'with' statement to + automatically handle the observation lifecycle within a code block. + + The created observation will be the child of the current span in the context. + + Args: + trace_context: Optional context for connecting to an existing trace + name: Name of the observation (e.g., function or operation name) + as_type: Type of observation to create (defaults to "span") + input: Input data for the operation (can be any JSON-serializable object) + output: Output data from the operation (can be any JSON-serializable object) + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + end_on_exit (default: True): Whether to end the span automatically when leaving the context manager. If False, the span must be manually ended to avoid memory leaks. + + The following parameters are only available when as_type="generation": + completion_start_time: When the model started generating the response + model: Name/identifier of the AI model used (e.g., "gpt-4") + model_parameters: Parameters used for the model (e.g., temperature, max_tokens) + usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) + cost_details: Cost information for the model call + prompt: Associated prompt template from Langfuse prompt management + + Returns: + A context manager that yields the appropriate observation type based on as_type + + Example: + ```python + # Create an agent observation + with langfuse.start_as_current_observation(name="planning-agent", as_type="agent") as agent: + # Do agent work + plan = create_plan() + agent.update(output=plan) + + # Create a tool observation + with langfuse.start_as_current_observation(name="web-search", as_type="tool") as tool: + # Do tool work + results = search_web(query) + tool.update(output=results) + + # Create a generation observation + with langfuse.start_as_current_observation( + name="answer-generation", + as_type="generation", + model="gpt-4" + ) as generation: + # Generate answer + response = llm.generate(...) + generation.update(output=response) + ``` + """ + # Delegate to existing methods for consistency + if as_type == "span": + return cast( + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ], + self.start_as_current_span( + trace_context=trace_context, + name=name, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + end_on_exit=end_on_exit, + ), + ) + + if as_type == "generation": + return cast( + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ], + self.start_as_current_generation( + trace_context=trace_context, + name=name, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + end_on_exit=end_on_exit, + ), + ) + + if trace_context: + trace_id = trace_context.get("trace_id", None) + parent_span_id = trace_context.get("parent_span_id", None) + + if trace_id: + remote_parent_span = self._create_remote_parent_span( + trace_id=trace_id, parent_span_id=parent_span_id + ) + + return cast( + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ], + self._create_span_with_parent_context( + as_type=as_type, + name=name, + remote_parent_span=remote_parent_span, + parent=None, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), + ) + + return cast( + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] + ], + self._start_as_current_otel_span_with_processed_media( + as_type=as_type, + name=name, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), + ) + def _get_span_class( self, as_type: ObservationTypeLiteral, ) -> type: """Get the appropriate span class based on as_type.""" - normalized_type = as_type.upper() + normalized_type = as_type.lower() - if normalized_type == "AGENT": + if normalized_type == "agent": return LangfuseAgent - elif normalized_type == "TOOL": + elif normalized_type == "tool": return LangfuseTool - elif normalized_type == "CHAIN": + elif normalized_type == "chain": return LangfuseChain - elif normalized_type == "RETRIEVER": + elif normalized_type == "retriever": return LangfuseRetriever - elif normalized_type == "EVALUATOR": + elif normalized_type == "evaluator": return LangfuseEvaluator - elif normalized_type == "EMBEDDING": + elif normalized_type == "embedding": return LangfuseEmbedding - elif normalized_type == "GUARDRAIL": + elif normalized_type == "guardrail": return LangfuseGuardrail - elif normalized_type == "GENERATION": + elif normalized_type == "generation": return LangfuseGeneration - elif normalized_type == "EVENT": + elif normalized_type == "event": return LangfuseEvent - elif normalized_type == "SPAN": + elif normalized_type == "span": return LangfuseSpan else: # Default to LangfuseSpan for unrecognized types @@ -778,7 +1075,9 @@ def _start_as_current_otel_span_with_processed_media( name=name, end_on_exit=end_on_exit if end_on_exit is not None else True, ) as otel_span: - span_class = self._get_span_class(as_type or "generation") # default was "generation" + span_class = self._get_span_class( + as_type or "generation" + ) # default was "generation" common_args = { "otel_span": otel_span, "langfuse_client": self, diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 323290ac8..0ab346993 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -25,9 +25,22 @@ LANGFUSE_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED, ) -from langfuse._client.constants import VALID_OBSERVATION_TYPES, ObservationTypeLiteralNoEvent +from langfuse._client.constants import ( + VALID_OBSERVATION_TYPES, + ObservationTypeLiteralNoEvent, +) from langfuse._client.get_client import _set_current_public_key, get_client -from langfuse._client.span import LangfuseGeneration, LangfuseSpan +from langfuse._client.span import ( + LangfuseGeneration, + LangfuseSpan, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, +) from langfuse.types import TraceContext F = TypeVar("F", bound=Callable[..., Any]) @@ -177,7 +190,6 @@ def sub_process(): ) def decorator(func: F) -> F: - return ( self._async_observe( func, @@ -255,25 +267,23 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: context_manager: Optional[ Union[ - _AgnosticContextManager[LangfuseGeneration], _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ] ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if as_type == "generation" - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=as_type, - ) + langfuse_client.start_as_current_observation( + name=final_name, + as_type=as_type, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early ) if langfuse_client else None @@ -362,25 +372,23 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: context_manager: Optional[ Union[ - _AgnosticContextManager[LangfuseGeneration], _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ] ] = ( - ( - langfuse_client.start_as_current_generation( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - ) - if as_type == "generation" - else langfuse_client.start_as_current_span( - name=final_name, - trace_context=trace_context, - input=input, - end_on_exit=False, # when returning a generator, closing on exit would be to early - as_type=as_type, - ) + langfuse_client.start_as_current_observation( + name=final_name, + as_type=as_type, + trace_context=trace_context, + input=input, + end_on_exit=False, # when returning a generator, closing on exit would be to early ) if langfuse_client else None diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 1308f60c7..0d05f0567 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -41,6 +41,7 @@ create_span_attributes, create_trace_attributes, ) +from langfuse._client.constants import ObservationTypeLiteral from langfuse.logger import langfuse_logger from langfuse.types import MapValue, ScoreDataType, SpanLevel @@ -64,16 +65,7 @@ def __init__( *, otel_span: otel_trace_api.Span, langfuse_client: "Langfuse", - as_type: Literal[ - "span", - "generation", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ], + as_type: ObservationTypeLiteral, input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -393,7 +385,7 @@ def _set_processed_span_attributes( self, *, span: otel_trace_api.Span, - as_type: Optional[Literal["span", "generation", "event"]] = None, + as_type: Optional[ObservationTypeLiteral] = None, input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -543,18 +535,6 @@ def __init__( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - as_type: Optional[ - Literal[ - "span", - "generation", - "event", - "agent", - "tool", - "chain", - "retriever", - "embedding", - ] - ] = None, ): """Initialize a new LangfuseSpan. @@ -1261,6 +1241,7 @@ def __init__( """ super().__init__( otel_span=otel_span, + # TODO: decided attributes as_type="span", # Use span-type attributes for all graph observations langfuse_client=langfuse_client, input=input, @@ -1338,7 +1319,7 @@ class LangfuseAgent(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseAgent span.""" - kwargs["observation_type"] = "agent" + kwargs["observation_type"] = "AGENT" super().__init__(**kwargs) @@ -1347,7 +1328,7 @@ class LangfuseTool(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseTool span.""" - kwargs["observation_type"] = "tool" + kwargs["observation_type"] = "TOOL" super().__init__(**kwargs) @@ -1356,7 +1337,7 @@ class LangfuseChain(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseChain span.""" - kwargs["observation_type"] = "chain" + kwargs["observation_type"] = "CHAIN" super().__init__(**kwargs) @@ -1365,7 +1346,7 @@ class LangfuseRetriever(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseRetriever span.""" - kwargs["observation_type"] = "retriever" + kwargs["observation_type"] = "RETRIEVER" super().__init__(**kwargs) From e41c018827d17598075a54b32fd952388b59ef94 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:09:11 +0200 Subject: [PATCH 19/66] fix some more types --- langfuse/_client/observe.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 0ab346993..914a841c5 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -280,7 +280,7 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: ] = ( langfuse_client.start_as_current_observation( name=final_name, - as_type=as_type, + as_type=as_type or "span", trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early @@ -385,7 +385,7 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: ] = ( langfuse_client.start_as_current_observation( name=final_name, - as_type=as_type, + as_type=as_type or "span", trace_context=trace_context, input=input, end_on_exit=False, # when returning a generator, closing on exit would be to early @@ -461,7 +461,17 @@ def _get_input_from_func_args( def _wrap_sync_generator_result( self, - langfuse_span_or_generation: Union[LangfuseSpan, LangfuseGeneration], + langfuse_span_or_generation: Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ], generator: Generator, transform_to_string: Optional[Callable[[Iterable], str]] = None, ) -> Any: @@ -487,7 +497,17 @@ def _wrap_sync_generator_result( async def _wrap_async_generator_result( self, - langfuse_span_or_generation: Union[LangfuseSpan, LangfuseGeneration], + langfuse_span_or_generation: Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ], generator: AsyncGenerator, transform_to_string: Optional[Callable[[Iterable], str]] = None, ) -> AsyncGenerator: From 5c3a510da3aefec97b63a9bbefd4f0d957a410fb Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:20:47 +0200 Subject: [PATCH 20/66] update SDK --- langfuse/_client/observe.py | 44 ++++++++++--------- .../ingestion/types/observation_type.py | 28 ++++++++++++ langfuse/api/resources/observations/client.py | 11 +++++ 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 914a841c5..4454c302d 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -266,16 +266,18 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: langfuse_client = get_client(public_key=public_key) context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseSpan], - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] ] ] = ( langfuse_client.start_as_current_observation( @@ -371,16 +373,18 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: langfuse_client = get_client(public_key=public_key) context_manager: Optional[ - Union[ - _AgnosticContextManager[LangfuseSpan], - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], + _AgnosticContextManager[ + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ] ] ] = ( langfuse_client.start_as_current_observation( diff --git a/langfuse/api/resources/ingestion/types/observation_type.py b/langfuse/api/resources/ingestion/types/observation_type.py index 0af377c3c..2f11300ff 100644 --- a/langfuse/api/resources/ingestion/types/observation_type.py +++ b/langfuse/api/resources/ingestion/types/observation_type.py @@ -10,12 +10,26 @@ class ObservationType(str, enum.Enum): SPAN = "SPAN" GENERATION = "GENERATION" EVENT = "EVENT" + AGENT = "AGENT" + TOOL = "TOOL" + CHAIN = "CHAIN" + RETRIEVER = "RETRIEVER" + EVALUATOR = "EVALUATOR" + EMBEDDING = "EMBEDDING" + GUARDRAIL = "GUARDRAIL" def visit( self, span: typing.Callable[[], T_Result], generation: typing.Callable[[], T_Result], event: typing.Callable[[], T_Result], + agent: typing.Callable[[], T_Result], + tool: typing.Callable[[], T_Result], + chain: typing.Callable[[], T_Result], + retriever: typing.Callable[[], T_Result], + evaluator: typing.Callable[[], T_Result], + embedding: typing.Callable[[], T_Result], + guardrail: typing.Callable[[], T_Result], ) -> T_Result: if self is ObservationType.SPAN: return span() @@ -23,3 +37,17 @@ def visit( return generation() if self is ObservationType.EVENT: return event() + if self is ObservationType.AGENT: + return agent() + if self is ObservationType.TOOL: + return tool() + if self is ObservationType.CHAIN: + return chain() + if self is ObservationType.RETRIEVER: + return retriever() + if self is ObservationType.EVALUATOR: + return evaluator() + if self is ObservationType.EMBEDDING: + return embedding() + if self is ObservationType.GUARDRAIL: + return guardrail() diff --git a/langfuse/api/resources/observations/client.py b/langfuse/api/resources/observations/client.py index 01bf60f78..b21981bb4 100644 --- a/langfuse/api/resources/observations/client.py +++ b/langfuse/api/resources/observations/client.py @@ -15,6 +15,7 @@ from ..commons.errors.method_not_allowed_error import MethodNotAllowedError from ..commons.errors.not_found_error import NotFoundError from ..commons.errors.unauthorized_error import UnauthorizedError +from ..commons.types.observation_level import ObservationLevel from ..commons.types.observations_view import ObservationsView from .types.observations_views import ObservationsViews @@ -100,6 +101,7 @@ def get_many( user_id: typing.Optional[str] = None, type: typing.Optional[str] = None, trace_id: typing.Optional[str] = None, + level: typing.Optional[ObservationLevel] = None, parent_observation_id: typing.Optional[str] = None, environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, from_start_time: typing.Optional[dt.datetime] = None, @@ -126,6 +128,9 @@ def get_many( trace_id : typing.Optional[str] + level : typing.Optional[ObservationLevel] + Optional filter for observations with a specific level (e.g. "DEBUG", "DEFAULT", "WARNING", "ERROR"). + parent_observation_id : typing.Optional[str] environment : typing.Optional[typing.Union[str, typing.Sequence[str]]] @@ -171,6 +176,7 @@ def get_many( "userId": user_id, "type": type, "traceId": trace_id, + "level": level, "parentObservationId": parent_observation_id, "environment": environment, "fromStartTime": serialize_datetime(from_start_time) @@ -299,6 +305,7 @@ async def get_many( user_id: typing.Optional[str] = None, type: typing.Optional[str] = None, trace_id: typing.Optional[str] = None, + level: typing.Optional[ObservationLevel] = None, parent_observation_id: typing.Optional[str] = None, environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, from_start_time: typing.Optional[dt.datetime] = None, @@ -325,6 +332,9 @@ async def get_many( trace_id : typing.Optional[str] + level : typing.Optional[ObservationLevel] + Optional filter for observations with a specific level (e.g. "DEBUG", "DEFAULT", "WARNING", "ERROR"). + parent_observation_id : typing.Optional[str] environment : typing.Optional[typing.Union[str, typing.Sequence[str]]] @@ -378,6 +388,7 @@ async def main() -> None: "userId": user_id, "type": type, "traceId": trace_id, + "level": level, "parentObservationId": parent_observation_id, "environment": environment, "fromStartTime": serialize_datetime(from_start_time) From dc5e199a919e0d0cb0b28c02f0cf42f831aad162 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:28:21 +0200 Subject: [PATCH 21/66] fix types --- langfuse/_client/client.py | 128 ++++++++++++++++-------------------- langfuse/_client/observe.py | 44 ++++++------- 2 files changed, 78 insertions(+), 94 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index e87b8ef9d..538bfc87f 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -731,16 +731,14 @@ def start_as_current_observation( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - ) -> _AgnosticContextManager[ - Union[ - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + ) -> Union[ + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ]: ... def start_as_current_observation( @@ -762,18 +760,16 @@ def start_as_current_observation( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, end_on_exit: Optional[bool] = None, - ) -> _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + ) -> Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ]: """Create a new observation and set it as the current span in a context manager. @@ -834,18 +830,16 @@ def start_as_current_observation( # Delegate to existing methods for consistency if as_type == "span": return cast( - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ], self.start_as_current_span( trace_context=trace_context, @@ -862,18 +856,16 @@ def start_as_current_observation( if as_type == "generation": return cast( - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ], self.start_as_current_generation( trace_context=trace_context, @@ -904,18 +896,16 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ], self._create_span_with_parent_context( as_type=as_type, @@ -939,18 +929,16 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ], self._start_as_current_otel_span_with_processed_media( as_type=as_type, diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 4454c302d..bed9a378b 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -266,18 +266,16 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: langfuse_client = get_client(public_key=public_key) context_manager: Optional[ - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ] ] = ( langfuse_client.start_as_current_observation( @@ -373,18 +371,16 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: langfuse_client = get_client(public_key=public_key) context_manager: Optional[ - _AgnosticContextManager[ - Union[ - LangfuseSpan, - LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ] + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseEmbedding], + _AgnosticContextManager[LangfuseGuardrail], ] ] = ( langfuse_client.start_as_current_observation( From 60f124bd102ff8ddcd7a11604284a4c6c642d6a7 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:28:34 +0200 Subject: [PATCH 22/66] add type checing isntructions --- .vscode/settings.json | 4 +- CLAUDE.md | 204 +- CONTRIBUTING.md | 7 + langfuse/langchain/CallbackHandler.py | 1 + poetry.lock | 2345 -------------------- pyproject.toml | 79 +- tests/test_manual_graph_instrumentation.py | 34 +- 7 files changed, 208 insertions(+), 2466 deletions(-) delete mode 100644 poetry.lock diff --git a/.vscode/settings.json b/.vscode/settings.json index 60c1c477b..41ac6ac98 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,9 @@ "prettier.documentSelectors": [ "**/*.{cjs,mjs,ts,tsx,astro,md,mdx,json,yaml,yml}" ], - "python.testing.pytestArgs": ["tests"], + "python.testing.pytestArgs": [ + "tests" + ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true } diff --git a/CLAUDE.md b/CLAUDE.md index b0f36e8d6..7514e08bb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,115 +4,175 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -This is the Langfuse Python SDK, a client library for accessing the Langfuse observability platform. The SDK provides integration with OpenTelemetry (OTel) for tracing, automatic instrumentation for popular LLM frameworks (OpenAI, Langchain, etc.), and direct API access to Langfuse's features. +This is the **Langfuse Python SDK**, an observability and analytics platform for AI applications. It provides tracing, evaluation, and analytics for LLM applications through multiple interfaces: decorators, low-level SDK, and integrations with popular AI libraries. ## Development Commands -### Setup +### Environment Setup ```bash -# Install Poetry plugins (one-time setup) -poetry self add poetry-dotenv-plugin -poetry self add poetry-bumpversion +# Using UV (preferred) +uv venv --python 3.12 +source .venv/bin/activate +uv sync -# Install all dependencies including optional extras +# Using Poetry (legacy) poetry install --all-extras - -# Setup pre-commit hooks poetry run pre-commit install ``` ### Testing ```bash -# Run all tests with verbose output +# Run all tests poetry run pytest -s -v --log-cli-level=INFO -# Run a specific test +# Run specific test poetry run pytest -s -v --log-cli-level=INFO tests/test_core_sdk.py::test_flush -# Run tests in parallel (faster) -poetry run pytest -s -v --log-cli-level=INFO -n auto +# Run with UV +uv run pytest -s -v --log-cli-level=INFO ``` +### Memory for Running Unit Tests +- To run unit tests you must always use the env file, use: `UV_ENV_FILE=.env uv run pytest -s -v --log-cli-level=INFO tests/TESTFILE::TEST_NAME` + ### Code Quality ```bash -# Format code with Ruff -poetry run ruff format . - -# Run linting (development config) -poetry run ruff check . +# Format code +ruff format . -# Run type checking -poetry run mypy . +# Run linter (development config) +ruff check . -# Run pre-commit hooks manually -poetry run pre-commit run --all-files +# Run linter (CI config) +ruff check --config ci.ruff.toml . ``` -### Building and Releasing +### Documentation ```bash -# Build the package -poetry build - -# Run release script (handles versioning, building, tagging, and publishing) -poetry run release - -# Generate documentation +# Generate SDK reference docs poetry run pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse + +# Serve docs locally +poetry run pdoc --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse ``` -## Architecture +## Architecture Overview ### Core Components -- **`langfuse/_client/`**: Main SDK implementation built on OpenTelemetry - - `client.py`: Core Langfuse client with OTel integration - - `span.py`: LangfuseSpan, LangfuseGeneration, LangfuseEvent classes - - `observe.py`: Decorator for automatic instrumentation - - `datasets.py`: Dataset management functionality - -- **`langfuse/api/`**: Auto-generated Fern API client - - Contains all API resources and types - - Generated from OpenAPI spec - do not manually edit these files - -- **`langfuse/_task_manager/`**: Background processing - - Media upload handling and queue management - - Score ingestion consumer - -- **Integration modules**: - - `langfuse/openai.py`: OpenAI instrumentation - - `langfuse/langchain/`: Langchain integration via CallbackHandler - -### Key Design Patterns - -The SDK is built on OpenTelemetry for observability, using: -- Spans for tracing LLM operations -- Attributes for metadata (see `LangfuseOtelSpanAttributes`) -- Resource management for efficient batching and flushing - -The client follows an async-first design with automatic batching of events and background flushing to the Langfuse API. +**Main SDK Client** (`langfuse/_client/client.py`) +- Built on OpenTelemetry foundations +- Provides span management for tracing (LangfuseSpan, LangfuseGeneration, LangfuseEvent) +- Thread-safe singleton pattern with multi-project support +- Handles both sync and async operations + +**Resource Manager** (`langfuse/_client/resource_manager.py`) +- Central coordination hub implementing thread-safe singleton +- Manages OpenTelemetry setup, API clients, background workers +- Handles media upload and score ingestion queues +- Provides graceful shutdown and resource cleanup + +**API Layer** (`langfuse/api/`) +- Auto-generated from OpenAPI spec using Fern +- Provides complete typed client for Langfuse API +- Organized by resources (prompts, datasets, observations, etc.) + +### SDK Interfaces + +**Three primary interaction patterns:** + +1. **Decorator Pattern** (`@observe`) + ```python + @observe(as_type="generation") + def my_llm_function(): + # Automatically traced + ``` + +2. **Low-level Client API** + ```python + langfuse = Langfuse() + span = langfuse.start_span(name="operation") + ``` + +3. **Integration Libraries** + ```python + from langfuse.openai import openai # Drop-in replacement + ``` + +### Integration Architecture + +**OpenAI Integration** (`langfuse/openai.py`) +- Drop-in replacement supporting both v0.x and v1.x +- Wraps all completion methods (chat, completions, streaming, async) +- Automatic metrics collection (tokens, cost, latency) + +**LangChain Integration** (`langfuse/langchain/`) +- CallbackHandler pattern for chain tracing +- Automatic span creation for chains, tools, and agents +- UUID mapping between LangChain runs and Langfuse spans + +### Background Processing + +**Task Manager** (`langfuse/_task_manager/`) +- Media upload processing with configurable workers +- Score ingestion with batching and retry logic +- Queue-based architecture with backpressure handling + +## Key Development Patterns + +### Multi-Project Safety +- Thread-safe singleton per public key prevents data leakage +- Project-scoped span processor filters ensure data isolation +- Disabled clients returned when project context is ambiguous + +### OpenTelemetry Foundation +- All tracing built on OTel primitives for standards compliance +- Custom span processor for Langfuse-specific export +- Proper context propagation across async boundaries + +### Testing Approach +- Comprehensive unit and integration tests +- API mocking through test wrappers +- Concurrency testing with ThreadPoolExecutor +- Proper resource cleanup in test teardown + +## File Structure Notes + +- `langfuse/_client/` - Core client implementation and tracing logic +- `langfuse/api/` - Auto-generated API client (excluded from linting) +- `langfuse/_utils/` - Utility functions for serialization, error handling, etc. +- `langfuse/_task_manager/` - Background processing workers +- `tests/` - Comprehensive test suite with integration tests +- `static/` - Test assets and sample files ## Configuration -Environment variables (defined in `_client/environment_variables.py`): -- `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY`: API credentials -- `LANGFUSE_HOST`: API endpoint (defaults to https://cloud.langfuse.com) -- `LANGFUSE_DEBUG`: Enable debug logging -- `LANGFUSE_TRACING_ENABLED`: Enable/disable tracing -- `LANGFUSE_SAMPLE_RATE`: Sampling rate for traces +### Environment Variables +Key environment variables for development: +- `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY` - API credentials +- `LANGFUSE_HOST` - Langfuse instance URL +- `LANGFUSE_DEBUG` - Enable debug logging +- `LANGFUSE_TRACING_ENABLED` - Enable/disable tracing -## Testing Notes +### Test Configuration +- Tests require `.env` file based on `.env.template` +- Some E2E tests are skipped by default (remove decorators to run) +- CI uses different ruff config (`ci.ruff.toml`) -- Create `.env` file based on `.env.template` for integration tests -- E2E tests with external APIs (OpenAI, SERP) are typically skipped in CI -- Remove `@pytest.mark.skip` decorators in test files to run external API tests -- Tests use `respx` for HTTP mocking and `pytest-httpserver` for test servers +## Release Process -## Important Files +```bash +# Automated release +poetry run release -- `pyproject.toml`: Poetry configuration, dependencies, and tool settings -- `ruff.toml`: Local development linting config (stricter) -- `ci.ruff.toml`: CI linting config (more permissive) -- `langfuse/version.py`: Version string (updated by release script) +# Manual release steps +poetry version patch +poetry build +git commit -am "chore: release v{version}" +git tag v{version} +git push --tags +poetry publish +``` ## API Generation diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 62b490f33..1d2bfd294 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,6 +21,13 @@ poetry install --all-extras poetry run pre-commit install ``` +### Type Checking + +To run type checking on the langfuse package, run: +```sh +poetry run mypy langfuse --no-error-summary +``` + ### Tests #### Setup diff --git a/langfuse/langchain/CallbackHandler.py b/langfuse/langchain/CallbackHandler.py index 03e73c3f2..d6cb6a7bf 100644 --- a/langfuse/langchain/CallbackHandler.py +++ b/langfuse/langchain/CallbackHandler.py @@ -458,6 +458,7 @@ def on_tool_start( input=input_str, metadata=meta, level="DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None, + as_type="tool", ) except Exception as e: diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index c3c1217e7..000000000 --- a/poetry.lock +++ /dev/null @@ -1,2345 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -files = [ - {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, - {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, -] - -[[package]] -name = "anyio" -version = "4.10.0" -description = "High-level concurrency and networking framework on top of asyncio or Trio" -optional = false -python-versions = ">=3.9" -files = [ - {file = "anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}, - {file = "anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} - -[package.extras] -trio = ["trio (>=0.26.1)"] - -[[package]] -name = "async-timeout" -version = "4.0.3" -description = "Timeout context manager for asyncio programs" -optional = true -python-versions = ">=3.7" -files = [ - {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, - {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, -] - -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "certifi" -version = "2025.8.3" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.7" -files = [ - {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, - {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, -] - -[[package]] -name = "cffi" -version = "1.17.1" -description = "Foreign Function Interface for Python calling C code." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, -] - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "cfgv" -version = "3.4.0" -description = "Validate configuration and produce human readable error messages." -optional = false -python-versions = ">=3.8" -files = [ - {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, - {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.3" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -optional = false -python-versions = ">=3.7" -files = [ - {file = "charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f"}, - {file = "charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849"}, - {file = "charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37"}, - {file = "charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce"}, - {file = "charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce"}, - {file = "charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557"}, - {file = "charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432"}, - {file = "charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca"}, - {file = "charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a"}, - {file = "charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14"}, -] - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "distlib" -version = "0.4.0" -description = "Distribution utilities" -optional = false -python-versions = "*" -files = [ - {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, - {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, -] - -[[package]] -name = "distro" -version = "1.9.0" -description = "Distro - an OS platform information API" -optional = false -python-versions = ">=3.6" -files = [ - {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, - {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, -] - -[[package]] -name = "exceptiongroup" -version = "1.3.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, -] - -[package.dependencies] -typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "execnet" -version = "2.1.1" -description = "execnet: rapid multi-Python deployment" -optional = false -python-versions = ">=3.8" -files = [ - {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, - {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, -] - -[package.extras] -testing = ["hatch", "pre-commit", "pytest", "tox"] - -[[package]] -name = "filelock" -version = "3.18.0" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.9" -files = [ - {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, - {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] -typing = ["typing-extensions (>=4.12.2)"] - -[[package]] -name = "googleapis-common-protos" -version = "1.70.0" -description = "Common protobufs used in Google APIs" -optional = false -python-versions = ">=3.7" -files = [ - {file = "googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8"}, - {file = "googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257"}, -] - -[package.dependencies] -protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" - -[package.extras] -grpc = ["grpcio (>=1.44.0,<2.0.0)"] - -[[package]] -name = "greenlet" -version = "3.2.4" -description = "Lightweight in-process concurrent programming" -optional = true -python-versions = ">=3.9" -files = [ - {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"}, - {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"}, - {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"}, - {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"}, - {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"}, - {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"}, - {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"}, - {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"}, - {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"}, - {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"}, - {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"}, - {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"}, - {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"}, - {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"}, - {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"}, - {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"}, - {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"}, - {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"}, - {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"}, - {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"}, - {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"}, - {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"}, - {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"}, - {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"}, - {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil", "setuptools"] - -[[package]] -name = "h11" -version = "0.16.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.8" -files = [ - {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, - {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, - {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.16" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<1.0)"] - -[[package]] -name = "httpx" -version = "0.28.1" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, - {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "identify" -version = "2.6.13" -description = "File identification library for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "identify-2.6.13-py2.py3-none-any.whl", hash = "sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b"}, - {file = "identify-2.6.13.tar.gz", hash = "sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32"}, -] - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.10" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.6" -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[package.extras] -all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] - -[[package]] -name = "importlib-metadata" -version = "8.7.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.9" -files = [ - {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, - {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, -] - -[package.dependencies] -zipp = ">=3.20" - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] -type = ["pytest-mypy"] - -[[package]] -name = "iniconfig" -version = "2.1.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.8" -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -description = "A very fast and expressive template engine." -optional = false -python-versions = ">=3.7" -files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, -] - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "jiter" -version = "0.10.0" -description = "Fast iterable JSON parser." -optional = false -python-versions = ">=3.9" -files = [ - {file = "jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303"}, - {file = "jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf"}, - {file = "jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90"}, - {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0"}, - {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee"}, - {file = "jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4"}, - {file = "jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5"}, - {file = "jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978"}, - {file = "jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5"}, - {file = "jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606"}, - {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605"}, - {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5"}, - {file = "jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7"}, - {file = "jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812"}, - {file = "jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b"}, - {file = "jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a"}, - {file = "jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95"}, - {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea"}, - {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b"}, - {file = "jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01"}, - {file = "jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49"}, - {file = "jiter-0.10.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0588107ec8e11b6f5ef0e0d656fb2803ac6cf94a96b2b9fc675c0e3ab5e8644"}, - {file = "jiter-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cafc4628b616dc32530c20ee53d71589816cf385dd9449633e910d596b1f5c8a"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520ef6d981172693786a49ff5b09eda72a42e539f14788124a07530f785c3ad6"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:554dedfd05937f8fc45d17ebdf298fe7e0c77458232bcb73d9fbbf4c6455f5b3"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc299da7789deacf95f64052d97f75c16d4fc8c4c214a22bf8d859a4288a1c2"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5161e201172de298a8a1baad95eb85db4fb90e902353b1f6a41d64ea64644e25"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2227db6ba93cb3e2bf67c87e594adde0609f146344e8207e8730364db27041"}, - {file = "jiter-0.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15acb267ea5e2c64515574b06a8bf393fbfee6a50eb1673614aa45f4613c0cca"}, - {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:901b92f2e2947dc6dfcb52fd624453862e16665ea909a08398dde19c0731b7f4"}, - {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d0cb9a125d5a3ec971a094a845eadde2db0de85b33c9f13eb94a0c63d463879e"}, - {file = "jiter-0.10.0-cp313-cp313-win32.whl", hash = "sha256:48a403277ad1ee208fb930bdf91745e4d2d6e47253eedc96e2559d1e6527006d"}, - {file = "jiter-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:75f9eb72ecb640619c29bf714e78c9c46c9c4eaafd644bf78577ede459f330d4"}, - {file = "jiter-0.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:28ed2a4c05a1f32ef0e1d24c2611330219fed727dae01789f4a335617634b1ca"}, - {file = "jiter-0.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a4c418b1ec86a195f1ca69da8b23e8926c752b685af665ce30777233dfe070"}, - {file = "jiter-0.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d7bfed2fe1fe0e4dda6ef682cee888ba444b21e7a6553e03252e4feb6cf0adca"}, - {file = "jiter-0.10.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:5e9251a5e83fab8d87799d3e1a46cb4b7f2919b895c6f4483629ed2446f66522"}, - {file = "jiter-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:023aa0204126fe5b87ccbcd75c8a0d0261b9abdbbf46d55e7ae9f8e22424eeb8"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c189c4f1779c05f75fc17c0c1267594ed918996a231593a21a5ca5438445216"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15720084d90d1098ca0229352607cd68256c76991f6b374af96f36920eae13c4"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f2fb68e5f1cfee30e2b2a09549a00683e0fde4c6a2ab88c94072fc33cb7426"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce541693355fc6da424c08b7edf39a2895f58d6ea17d92cc2b168d20907dee12"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c50c40272e189d50006ad5c73883caabb73d4e9748a688b216e85a9a9ca3b9"}, - {file = "jiter-0.10.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa3402a2ff9815960e0372a47b75c76979d74402448509ccd49a275fa983ef8a"}, - {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:1956f934dca32d7bb647ea21d06d93ca40868b505c228556d3373cbd255ce853"}, - {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:fcedb049bdfc555e261d6f65a6abe1d5ad68825b7202ccb9692636c70fcced86"}, - {file = "jiter-0.10.0-cp314-cp314-win32.whl", hash = "sha256:ac509f7eccca54b2a29daeb516fb95b6f0bd0d0d8084efaf8ed5dfc7b9f0b357"}, - {file = "jiter-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ed975b83a2b8639356151cef5c0d597c68376fc4922b45d0eb384ac058cfa00"}, - {file = "jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5"}, - {file = "jiter-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bd6292a43c0fc09ce7c154ec0fa646a536b877d1e8f2f96c19707f65355b5a4d"}, - {file = "jiter-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39de429dcaeb6808d75ffe9effefe96a4903c6a4b376b2f6d08d77c1aaee2f18"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52ce124f13a7a616fad3bb723f2bfb537d78239d1f7f219566dc52b6f2a9e48d"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:166f3606f11920f9a1746b2eea84fa2c0a5d50fd313c38bdea4edc072000b0af"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28dcecbb4ba402916034fc14eba7709f250c4d24b0c43fc94d187ee0580af181"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86c5aa6910f9bebcc7bc4f8bc461aff68504388b43bfe5e5c0bd21efa33b52f4"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ceeb52d242b315d7f1f74b441b6a167f78cea801ad7c11c36da77ff2d42e8a28"}, - {file = "jiter-0.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff76d8887c8c8ee1e772274fcf8cc1071c2c58590d13e33bd12d02dc9a560397"}, - {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a9be4d0fa2b79f7222a88aa488bd89e2ae0a0a5b189462a12def6ece2faa45f1"}, - {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ab7fd8738094139b6c1ab1822d6f2000ebe41515c537235fd45dabe13ec9324"}, - {file = "jiter-0.10.0-cp39-cp39-win32.whl", hash = "sha256:5f51e048540dd27f204ff4a87f5d79294ea0aa3aa552aca34934588cf27023cf"}, - {file = "jiter-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b28302349dc65703a9e4ead16f163b1c339efffbe1049c30a44b001a2a4fff9"}, - {file = "jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500"}, -] - -[[package]] -name = "jsonpatch" -version = "1.33" -description = "Apply JSON-Patches (RFC 6902)" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" -files = [ - {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, - {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, -] - -[package.dependencies] -jsonpointer = ">=1.9" - -[[package]] -name = "jsonpointer" -version = "3.0.0" -description = "Identify specific nodes in a JSON document (RFC 6901)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, - {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, -] - -[[package]] -name = "langchain" -version = "0.3.27" -description = "Building applications with LLMs through composability" -optional = true -python-versions = "<4.0,>=3.9" -files = [ - {file = "langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798"}, - {file = "langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62"}, -] - -[package.dependencies] -async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} -langchain-core = ">=0.3.72,<1.0.0" -langchain-text-splitters = ">=0.3.9,<1.0.0" -langsmith = ">=0.1.17" -pydantic = ">=2.7.4,<3.0.0" -PyYAML = ">=5.3" -requests = ">=2,<3" -SQLAlchemy = ">=1.4,<3" - -[package.extras] -anthropic = ["langchain-anthropic"] -aws = ["langchain-aws"] -azure-ai = ["langchain-azure-ai"] -cohere = ["langchain-cohere"] -community = ["langchain-community"] -deepseek = ["langchain-deepseek"] -fireworks = ["langchain-fireworks"] -google-genai = ["langchain-google-genai"] -google-vertexai = ["langchain-google-vertexai"] -groq = ["langchain-groq"] -huggingface = ["langchain-huggingface"] -mistralai = ["langchain-mistralai"] -ollama = ["langchain-ollama"] -openai = ["langchain-openai"] -perplexity = ["langchain-perplexity"] -together = ["langchain-together"] -xai = ["langchain-xai"] - -[[package]] -name = "langchain-core" -version = "0.3.74" -description = "Building applications with LLMs through composability" -optional = false -python-versions = ">=3.9" -files = [ - {file = "langchain_core-0.3.74-py3-none-any.whl", hash = "sha256:088338b5bc2f6a66892f9afc777992c24ee3188f41cbc603d09181e34a228ce7"}, - {file = "langchain_core-0.3.74.tar.gz", hash = "sha256:ff604441aeade942fbcc0a3860a592daba7671345230c2078ba2eb5f82b6ba76"}, -] - -[package.dependencies] -jsonpatch = ">=1.33,<2.0" -langsmith = ">=0.3.45" -packaging = ">=23.2" -pydantic = ">=2.7.4" -PyYAML = ">=5.3" -tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0" -typing-extensions = ">=4.7" - -[[package]] -name = "langchain-openai" -version = "0.2.14" -description = "An integration package connecting OpenAI and LangChain" -optional = false -python-versions = "<4.0,>=3.9" -files = [ - {file = "langchain_openai-0.2.14-py3-none-any.whl", hash = "sha256:d232496662f79ece9a11caf7d798ba863e559c771bc366814f7688e0fe664fe8"}, - {file = "langchain_openai-0.2.14.tar.gz", hash = "sha256:7a514f309e356b182a337c0ed36ab3fbe34d9834a235a3b85cb7f91ae775d978"}, -] - -[package.dependencies] -langchain-core = ">=0.3.27,<0.4.0" -openai = ">=1.58.1,<2.0.0" -tiktoken = ">=0.7,<1" - -[[package]] -name = "langchain-text-splitters" -version = "0.3.9" -description = "LangChain text splitting utilities" -optional = true -python-versions = ">=3.9" -files = [ - {file = "langchain_text_splitters-0.3.9-py3-none-any.whl", hash = "sha256:cee0bb816211584ea79cc79927317c358543f40404bcfdd69e69ba3ccde54401"}, - {file = "langchain_text_splitters-0.3.9.tar.gz", hash = "sha256:7cd1e5a3aaf609979583eeca2eb34177622570b8fa8f586a605c6b1c34e7ebdb"}, -] - -[package.dependencies] -langchain-core = ">=0.3.72,<1.0.0" - -[[package]] -name = "langgraph" -version = "0.2.76" -description = "Building stateful, multi-actor applications with LLMs" -optional = false -python-versions = "<4.0,>=3.9.0" -files = [ - {file = "langgraph-0.2.76-py3-none-any.whl", hash = "sha256:076b8b5d2fc5a9761c46a7618430cfa5c978a8012257c43cbc127b27e0fd7872"}, - {file = "langgraph-0.2.76.tar.gz", hash = "sha256:688f8dcd9b6797ba78384599e0de944773000c75156ad1e186490e99e89fa5c0"}, -] - -[package.dependencies] -langchain-core = ">=0.2.43,<0.3.0 || >0.3.0,<0.3.1 || >0.3.1,<0.3.2 || >0.3.2,<0.3.3 || >0.3.3,<0.3.4 || >0.3.4,<0.3.5 || >0.3.5,<0.3.6 || >0.3.6,<0.3.7 || >0.3.7,<0.3.8 || >0.3.8,<0.3.9 || >0.3.9,<0.3.10 || >0.3.10,<0.3.11 || >0.3.11,<0.3.12 || >0.3.12,<0.3.13 || >0.3.13,<0.3.14 || >0.3.14,<0.3.15 || >0.3.15,<0.3.16 || >0.3.16,<0.3.17 || >0.3.17,<0.3.18 || >0.3.18,<0.3.19 || >0.3.19,<0.3.20 || >0.3.20,<0.3.21 || >0.3.21,<0.3.22 || >0.3.22,<0.4.0" -langgraph-checkpoint = ">=2.0.10,<3.0.0" -langgraph-sdk = ">=0.1.42,<0.2.0" - -[[package]] -name = "langgraph-checkpoint" -version = "2.1.1" -description = "Library with base interfaces for LangGraph checkpoint savers." -optional = false -python-versions = ">=3.9" -files = [ - {file = "langgraph_checkpoint-2.1.1-py3-none-any.whl", hash = "sha256:5a779134fd28134a9a83d078be4450bbf0e0c79fdf5e992549658899e6fc5ea7"}, - {file = "langgraph_checkpoint-2.1.1.tar.gz", hash = "sha256:72038c0f9e22260cb9bff1f3ebe5eb06d940b7ee5c1e4765019269d4f21cf92d"}, -] - -[package.dependencies] -langchain-core = ">=0.2.38" -ormsgpack = ">=1.10.0" - -[[package]] -name = "langgraph-sdk" -version = "0.1.74" -description = "SDK for interacting with LangGraph API" -optional = false -python-versions = ">=3.9" -files = [ - {file = "langgraph_sdk-0.1.74-py3-none-any.whl", hash = "sha256:3a265c3757fe0048adad4391d10486db63ef7aa5a2cbd22da22d4503554cb890"}, - {file = "langgraph_sdk-0.1.74.tar.gz", hash = "sha256:7450e0db5b226cc2e5328ca22c5968725873630ef47c4206a30707cb25dc3ad6"}, -] - -[package.dependencies] -httpx = ">=0.25.2" -orjson = ">=3.10.1" - -[[package]] -name = "langsmith" -version = "0.4.14" -description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -optional = false -python-versions = ">=3.9" -files = [ - {file = "langsmith-0.4.14-py3-none-any.whl", hash = "sha256:b6d070ac425196947d2a98126fb0e35f3b8c001a2e6e5b7049dd1c56f0767d0b"}, - {file = "langsmith-0.4.14.tar.gz", hash = "sha256:4d29c7a9c85b20ba813ab9c855407bccdf5eb4f397f512ffa89959b2a2cb83ed"}, -] - -[package.dependencies] -httpx = ">=0.23.0,<1" -orjson = {version = ">=3.9.14", markers = "platform_python_implementation != \"PyPy\""} -packaging = ">=23.2" -pydantic = ">=1,<3" -requests = ">=2.0.0" -requests-toolbelt = ">=1.0.0" -zstandard = ">=0.23.0" - -[package.extras] -langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2)"] -openai-agents = ["openai-agents (>=0.0.3)"] -otel = ["opentelemetry-api (>=1.30.0)", "opentelemetry-exporter-otlp-proto-http (>=1.30.0)", "opentelemetry-sdk (>=1.30.0)"] -pytest = ["pytest (>=7.0.0)", "rich (>=13.9.4)", "vcrpy (>=7.0.0)"] -vcr = ["vcrpy (>=7.0.0)"] - -[[package]] -name = "markupsafe" -version = "3.0.2" -description = "Safely add untrusted strings to HTML/XML markup." -optional = false -python-versions = ">=3.9" -files = [ - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, - {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, - {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, - {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, - {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "mypy" -version = "1.17.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972"}, - {file = "mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df"}, - {file = "mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390"}, - {file = "mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94"}, - {file = "mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58"}, - {file = "mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd"}, - {file = "mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b"}, - {file = "mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5"}, - {file = "mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb"}, - {file = "mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056"}, - {file = "mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341"}, - {file = "mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb"}, - {file = "mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7"}, - {file = "mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6"}, - {file = "mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849"}, - {file = "mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14"}, - {file = "mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733"}, - {file = "mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0"}, - {file = "mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a"}, - {file = "mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91"}, - {file = "mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9"}, - {file = "mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8"}, - {file = "mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8"}, - {file = "mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259"}, - {file = "mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d"}, - {file = "mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9"}, - {file = "mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01"}, -] - -[package.dependencies] -mypy_extensions = ">=1.0.0" -pathspec = ">=0.9.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing_extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -faster-cache = ["orjson"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.1.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, - {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "openai" -version = "1.99.9" -description = "The official Python library for the openai API" -optional = false -python-versions = ">=3.8" -files = [ - {file = "openai-1.99.9-py3-none-any.whl", hash = "sha256:9dbcdb425553bae1ac5d947147bebbd630d91bbfc7788394d4c4f3a35682ab3a"}, - {file = "openai-1.99.9.tar.gz", hash = "sha256:f2082d155b1ad22e83247c3de3958eb4255b20ccf4a1de2e6681b6957b554e92"}, -] - -[package.dependencies] -anyio = ">=3.5.0,<5" -distro = ">=1.7.0,<2" -httpx = ">=0.23.0,<1" -jiter = ">=0.4.0,<1" -pydantic = ">=1.9.0,<3" -sniffio = "*" -tqdm = ">4" -typing-extensions = ">=4.11,<5" - -[package.extras] -aiohttp = ["aiohttp", "httpx-aiohttp (>=0.1.8)"] -datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -realtime = ["websockets (>=13,<16)"] -voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"] - -[[package]] -name = "opentelemetry-api" -version = "1.36.0" -description = "OpenTelemetry Python API" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_api-1.36.0-py3-none-any.whl", hash = "sha256:02f20bcacf666e1333b6b1f04e647dc1d5111f86b8e510238fcc56d7762cda8c"}, - {file = "opentelemetry_api-1.36.0.tar.gz", hash = "sha256:9a72572b9c416d004d492cbc6e61962c0501eaf945ece9b5a0f56597d8348aa0"}, -] - -[package.dependencies] -importlib-metadata = ">=6.0,<8.8.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-exporter-otlp-proto-common" -version = "1.36.0" -description = "OpenTelemetry Protobuf encoding" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_exporter_otlp_proto_common-1.36.0-py3-none-any.whl", hash = "sha256:0fc002a6ed63eac235ada9aa7056e5492e9a71728214a61745f6ad04b923f840"}, - {file = "opentelemetry_exporter_otlp_proto_common-1.36.0.tar.gz", hash = "sha256:6c496ccbcbe26b04653cecadd92f73659b814c6e3579af157d8716e5f9f25cbf"}, -] - -[package.dependencies] -opentelemetry-proto = "1.36.0" - -[[package]] -name = "opentelemetry-exporter-otlp-proto-http" -version = "1.36.0" -description = "OpenTelemetry Collector Protobuf over HTTP Exporter" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_exporter_otlp_proto_http-1.36.0-py3-none-any.whl", hash = "sha256:3d769f68e2267e7abe4527f70deb6f598f40be3ea34c6adc35789bea94a32902"}, - {file = "opentelemetry_exporter_otlp_proto_http-1.36.0.tar.gz", hash = "sha256:dd3637f72f774b9fc9608ab1ac479f8b44d09b6fb5b2f3df68a24ad1da7d356e"}, -] - -[package.dependencies] -googleapis-common-protos = ">=1.52,<2.0" -opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.36.0" -opentelemetry-proto = "1.36.0" -opentelemetry-sdk = ">=1.36.0,<1.37.0" -requests = ">=2.7,<3.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-proto" -version = "1.36.0" -description = "OpenTelemetry Python Proto" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_proto-1.36.0-py3-none-any.whl", hash = "sha256:151b3bf73a09f94afc658497cf77d45a565606f62ce0c17acb08cd9937ca206e"}, - {file = "opentelemetry_proto-1.36.0.tar.gz", hash = "sha256:0f10b3c72f74c91e0764a5ec88fd8f1c368ea5d9c64639fb455e2854ef87dd2f"}, -] - -[package.dependencies] -protobuf = ">=5.0,<7.0" - -[[package]] -name = "opentelemetry-sdk" -version = "1.36.0" -description = "OpenTelemetry Python SDK" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_sdk-1.36.0-py3-none-any.whl", hash = "sha256:19fe048b42e98c5c1ffe85b569b7073576ad4ce0bcb6e9b4c6a39e890a6c45fb"}, - {file = "opentelemetry_sdk-1.36.0.tar.gz", hash = "sha256:19c8c81599f51b71670661ff7495c905d8fdf6976e41622d5245b791b06fa581"}, -] - -[package.dependencies] -opentelemetry-api = "1.36.0" -opentelemetry-semantic-conventions = "0.57b0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "opentelemetry-semantic-conventions" -version = "0.57b0" -description = "OpenTelemetry Semantic Conventions" -optional = false -python-versions = ">=3.9" -files = [ - {file = "opentelemetry_semantic_conventions-0.57b0-py3-none-any.whl", hash = "sha256:757f7e76293294f124c827e514c2a3144f191ef175b069ce8d1211e1e38e9e78"}, - {file = "opentelemetry_semantic_conventions-0.57b0.tar.gz", hash = "sha256:609a4a79c7891b4620d64c7aac6898f872d790d75f22019913a660756f27ff32"}, -] - -[package.dependencies] -opentelemetry-api = "1.36.0" -typing-extensions = ">=4.5.0" - -[[package]] -name = "orjson" -version = "3.11.2" -description = "" -optional = false -python-versions = ">=3.9" -files = [ - {file = "orjson-3.11.2-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d6b8a78c33496230a60dc9487118c284c15ebdf6724386057239641e1eb69761"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc04036eeae11ad4180d1f7b5faddb5dab1dee49ecd147cd431523869514873b"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c04325839c5754c253ff301cee8aaed7442d974860a44447bb3be785c411c27"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32769e04cd7fdc4a59854376211145a1bbbc0aea5e9d6c9755d3d3c301d7c0df"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff285d14917ea1408a821786e3677c5261fa6095277410409c694b8e7720ae0"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2662f908114864b63ff75ffe6ffacf996418dd6cc25e02a72ad4bda81b1ec45a"}, - {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab463cf5d08ad6623a4dac1badd20e88a5eb4b840050c4812c782e3149fe2334"}, - {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:64414241bde943cbf3c00d45fcb5223dca6d9210148ba984aae6b5d63294502b"}, - {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:7773e71c0ae8c9660192ff144a3d69df89725325e3d0b6a6bb2c50e5ebaf9b84"}, - {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:652ca14e283b13ece35bf3a86503c25592f294dbcfc5bb91b20a9c9a62a3d4be"}, - {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:26e99e98df8990ecfe3772bbdd7361f602149715c2cbc82e61af89bfad9528a4"}, - {file = "orjson-3.11.2-cp310-cp310-win32.whl", hash = "sha256:5814313b3e75a2be7fe6c7958201c16c4560e21a813dbad25920752cecd6ad66"}, - {file = "orjson-3.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:dc471ce2225ab4c42ca672f70600d46a8b8e28e8d4e536088c1ccdb1d22b35ce"}, - {file = "orjson-3.11.2-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:888b64ef7eaeeff63f773881929434a5834a6a140a63ad45183d59287f07fc6a"}, - {file = "orjson-3.11.2-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:83387cc8b26c9fa0ae34d1ea8861a7ae6cff8fb3e346ab53e987d085315a728e"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7e35f003692c216d7ee901b6b916b5734d6fc4180fcaa44c52081f974c08e17"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4a0a4c29ae90b11d0c00bcc31533854d89f77bde2649ec602f512a7e16e00640"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:585d712b1880f68370108bc5534a257b561672d1592fae54938738fe7f6f1e33"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d08e342a7143f8a7c11f1c4033efe81acbd3c98c68ba1b26b96080396019701f"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c0f84fc50398773a702732c87cd622737bf11c0721e6db3041ac7802a686fb"}, - {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:140f84e3c8d4c142575898c91e3981000afebf0333df753a90b3435d349a5fe5"}, - {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96304a2b7235e0f3f2d9363ddccdbfb027d27338722fe469fe656832a017602e"}, - {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d7612bb227d5d9582f1f50a60bd55c64618fc22c4a32825d233a4f2771a428a"}, - {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a134587d18fe493befc2defffef2a8d27cfcada5696cb7234de54a21903ae89a"}, - {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0b84455e60c4bc12c1e4cbaa5cfc1acdc7775a9da9cec040e17232f4b05458bd"}, - {file = "orjson-3.11.2-cp311-cp311-win32.whl", hash = "sha256:f0660efeac223f0731a70884e6914a5f04d613b5ae500744c43f7bf7b78f00f9"}, - {file = "orjson-3.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:955811c8405251d9e09cbe8606ad8fdef49a451bcf5520095a5ed38c669223d8"}, - {file = "orjson-3.11.2-cp311-cp311-win_arm64.whl", hash = "sha256:2e4d423a6f838552e3a6d9ec734b729f61f88b1124fd697eab82805ea1a2a97d"}, - {file = "orjson-3.11.2-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:901d80d349d8452162b3aa1afb82cec5bee79a10550660bc21311cc61a4c5486"}, - {file = "orjson-3.11.2-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:cf3bd3967a360e87ee14ed82cb258b7f18c710dacf3822fb0042a14313a673a1"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26693dde66910078229a943e80eeb99fdce6cd2c26277dc80ead9f3ab97d2131"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad4c8acb50a28211c33fc7ef85ddf5cb18d4636a5205fd3fa2dce0411a0e30c"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:994181e7f1725bb5f2d481d7d228738e0743b16bf319ca85c29369c65913df14"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbb79a0476393c07656b69c8e763c3cc925fa8e1d9e9b7d1f626901bb5025448"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:191ed27a1dddb305083d8716af413d7219f40ec1d4c9b0e977453b4db0d6fb6c"}, - {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0afb89f16f07220183fd00f5f297328ed0a68d8722ad1b0c8dcd95b12bc82804"}, - {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ab6e6b4e93b1573a026b6ec16fca9541354dd58e514b62c558b58554ae04307"}, - {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9cb23527efb61fb75527df55d20ee47989c4ee34e01a9c98ee9ede232abf6219"}, - {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a4dd1268e4035af21b8a09e4adf2e61f87ee7bf63b86d7bb0a237ac03fad5b45"}, - {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff8b155b145eaf5a9d94d2c476fbe18d6021de93cf36c2ae2c8c5b775763f14e"}, - {file = "orjson-3.11.2-cp312-cp312-win32.whl", hash = "sha256:ae3bb10279d57872f9aba68c9931aa71ed3b295fa880f25e68da79e79453f46e"}, - {file = "orjson-3.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:d026e1967239ec11a2559b4146a61d13914504b396f74510a1c4d6b19dfd8732"}, - {file = "orjson-3.11.2-cp312-cp312-win_arm64.whl", hash = "sha256:59f8d5ad08602711af9589375be98477d70e1d102645430b5a7985fdbf613b36"}, - {file = "orjson-3.11.2-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a079fdba7062ab396380eeedb589afb81dc6683f07f528a03b6f7aae420a0219"}, - {file = "orjson-3.11.2-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:6a5f62ebbc530bb8bb4b1ead103647b395ba523559149b91a6c545f7cd4110ad"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7df6c7b8b0931feb3420b72838c3e2ba98c228f7aa60d461bc050cf4ca5f7b2"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6f59dfea7da1fced6e782bb3699718088b1036cb361f36c6e4dd843c5111aefe"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edf49146520fef308c31aa4c45b9925fd9c7584645caca7c0c4217d7900214ae"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50995bbeb5d41a32ad15e023305807f561ac5dcd9bd41a12c8d8d1d2c83e44e6"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cc42960515076eb639b705f105712b658c525863d89a1704d984b929b0577d1"}, - {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c56777cab2a7b2a8ea687fedafb84b3d7fdafae382165c31a2adf88634c432fa"}, - {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:07349e88025b9b5c783077bf7a9f401ffbfb07fd20e86ec6fc5b7432c28c2c5e"}, - {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:45841fbb79c96441a8c58aa29ffef570c5df9af91f0f7a9572e5505e12412f15"}, - {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:13d8d8db6cd8d89d4d4e0f4161acbbb373a4d2a4929e862d1d2119de4aa324ac"}, - {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51da1ee2178ed09c00d09c1b953e45846bbc16b6420965eb7a913ba209f606d8"}, - {file = "orjson-3.11.2-cp313-cp313-win32.whl", hash = "sha256:51dc033df2e4a4c91c0ba4f43247de99b3cbf42ee7a42ee2b2b2f76c8b2f2cb5"}, - {file = "orjson-3.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:29d91d74942b7436f29b5d1ed9bcfc3f6ef2d4f7c4997616509004679936650d"}, - {file = "orjson-3.11.2-cp313-cp313-win_arm64.whl", hash = "sha256:4ca4fb5ac21cd1e48028d4f708b1bb13e39c42d45614befd2ead004a8bba8535"}, - {file = "orjson-3.11.2-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3dcba7101ea6a8d4ef060746c0f2e7aa8e2453a1012083e1ecce9726d7554cb7"}, - {file = "orjson-3.11.2-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:15d17bdb76a142e1f55d91913e012e6e6769659daa6bfef3ef93f11083137e81"}, - {file = "orjson-3.11.2-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:53c9e81768c69d4b66b8876ec3c8e431c6e13477186d0db1089d82622bccd19f"}, - {file = "orjson-3.11.2-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d4f13af59a7b84c1ca6b8a7ab70d608f61f7c44f9740cd42409e6ae7b6c8d8b7"}, - {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bde64aa469b5ee46cc960ed241fae3721d6a8801dacb2ca3466547a2535951e4"}, - {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b5ca86300aeb383c8fa759566aca065878d3d98c3389d769b43f0a2e84d52c5f"}, - {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:24e32a558ebed73a6a71c8f1cbc163a7dd5132da5270ff3d8eeb727f4b6d1bc7"}, - {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e36319a5d15b97e4344110517450396845cc6789aed712b1fbf83c1bd95792f6"}, - {file = "orjson-3.11.2-cp314-cp314-win32.whl", hash = "sha256:40193ada63fab25e35703454d65b6afc71dbc65f20041cb46c6d91709141ef7f"}, - {file = "orjson-3.11.2-cp314-cp314-win_amd64.whl", hash = "sha256:7c8ac5f6b682d3494217085cf04dadae66efee45349ad4ee2a1da3c97e2305a8"}, - {file = "orjson-3.11.2-cp314-cp314-win_arm64.whl", hash = "sha256:21cf261e8e79284242e4cb1e5924df16ae28255184aafeff19be1405f6d33f67"}, - {file = "orjson-3.11.2-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:957f10c7b5bce3d3f2ad577f3b307c784f5dabafcce3b836229c269c11841c86"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a669e31ab8eb466c9142ac7a4be2bb2758ad236a31ef40dcd4cf8774ab40f33"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:adedf7d887416c51ad49de3c53b111887e0b63db36c6eb9f846a8430952303d8"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ad8873979659ad98fc56377b9c5b93eb8059bf01e6412f7abf7dbb3d637a991"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9482ef83b2bf796157566dd2d2742a8a1e377045fe6065fa67acb1cb1d21d9a3"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73cee7867c1fcbd1cc5b6688b3e13db067f968889242955780123a68b3d03316"}, - {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:465166773265f3cc25db10199f5d11c81898a309e26a2481acf33ddbec433fda"}, - {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc000190a7b1d2d8e36cba990b3209a1e15c0efb6c7750e87f8bead01afc0d46"}, - {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:df3fdd8efa842ccbb81135d6f58a73512f11dba02ed08d9466261c2e9417af4e"}, - {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3dacfc621be3079ec69e0d4cb32e3764067726e0ef5a5576428f68b6dc85b4f6"}, - {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9fdff73a029cde5f4a1cf5ec9dbc6acab98c9ddd69f5580c2b3f02ce43ba9f9f"}, - {file = "orjson-3.11.2-cp39-cp39-win32.whl", hash = "sha256:b1efbdc479c6451138c3733e415b4d0e16526644e54e2f3689f699c4cda303bf"}, - {file = "orjson-3.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:c9ec0cc0d4308cad1e38a1ee23b64567e2ff364c2a3fe3d6cbc69cf911c45712"}, - {file = "orjson-3.11.2.tar.gz", hash = "sha256:91bdcf5e69a8fd8e8bdb3de32b31ff01d2bd60c1e8d5fe7d5afabdcf19920309"}, -] - -[[package]] -name = "ormsgpack" -version = "1.10.0" -description = "Fast, correct Python msgpack library supporting dataclasses, datetimes, and numpy" -optional = false -python-versions = ">=3.9" -files = [ - {file = "ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5"}, - {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7"}, - {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84"}, - {file = "ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07"}, - {file = "ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e"}, - {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5"}, - {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08"}, - {file = "ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a"}, - {file = "ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5"}, - {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd"}, - {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0"}, - {file = "ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722"}, - {file = "ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e"}, - {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935"}, - {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668"}, - {file = "ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69"}, - {file = "ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453"}, - {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3"}, - {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d"}, - {file = "ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749"}, - {file = "ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16"}, -] - -[[package]] -name = "packaging" -version = "25.0" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, - {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "pdoc" -version = "14.7.0" -description = "API Documentation for Python Projects" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pdoc-14.7.0-py3-none-any.whl", hash = "sha256:72377a907efc6b2c5b3c56b717ef34f11d93621dced3b663f3aede0b844c0ad2"}, - {file = "pdoc-14.7.0.tar.gz", hash = "sha256:2d28af9c0acc39180744ad0543e4bbc3223ecba0d1302db315ec521c51f71f93"}, -] - -[package.dependencies] -Jinja2 = ">=2.11.0" -MarkupSafe = "*" -pygments = ">=2.12.0" - -[package.extras] -dev = ["hypothesis", "mypy", "pdoc-pyo3-sample-library (==1.0.11)", "pygments (>=2.14.0)", "pytest", "pytest-cov", "pytest-timeout", "ruff", "tox", "types-pygments"] - -[[package]] -name = "platformdirs" -version = "4.3.8" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.9" -files = [ - {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, - {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] -type = ["mypy (>=1.14.1)"] - -[[package]] -name = "pluggy" -version = "1.6.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, - {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["coverage", "pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "3.8.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -optional = false -python-versions = ">=3.9" -files = [ - {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, - {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, -] - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -virtualenv = ">=20.10.0" - -[[package]] -name = "protobuf" -version = "6.31.1" -description = "" -optional = false -python-versions = ">=3.9" -files = [ - {file = "protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9"}, - {file = "protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447"}, - {file = "protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39"}, - {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6"}, - {file = "protobuf-6.31.1-cp39-cp39-win32.whl", hash = "sha256:0414e3aa5a5f3ff423828e1e6a6e907d6c65c1d5b7e6e975793d5590bdeecc16"}, - {file = "protobuf-6.31.1-cp39-cp39-win_amd64.whl", hash = "sha256:8764cf4587791e7564051b35524b72844f845ad0bb011704c3736cce762d8fe9"}, - {file = "protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e"}, - {file = "protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a"}, -] - -[[package]] -name = "pycparser" -version = "2.22" -description = "C parser in Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, - {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, -] - -[[package]] -name = "pydantic" -version = "2.11.7" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"}, - {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.33.2" -typing-extensions = ">=4.12.2" -typing-inspection = ">=0.4.0" - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.33.2" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, - {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, - {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, - {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, - {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, - {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, - {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, - {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, - {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, - {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, - {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, - {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, - {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, - {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, - {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, - {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, - {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, - {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, - {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, - {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, - {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, - {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, - {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, - {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, - {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, - {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, - {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, - {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, - {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, - {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pygments" -version = "2.19.2" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, - {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pytest" -version = "8.4.1" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"}, - {file = "pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"}, -] - -[package.dependencies] -colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} -iniconfig = ">=1" -packaging = ">=20" -pluggy = ">=1.5,<2" -pygments = ">=2.7.2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.8" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, -] - -[package.dependencies] -pytest = ">=7.0.0,<9" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - -[[package]] -name = "pytest-httpserver" -version = "1.1.3" -description = "pytest-httpserver is a httpserver for pytest" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pytest_httpserver-1.1.3-py3-none-any.whl", hash = "sha256:5f84757810233e19e2bb5287f3826a71c97a3740abe3a363af9155c0f82fdbb9"}, - {file = "pytest_httpserver-1.1.3.tar.gz", hash = "sha256:af819d6b533f84b4680b9416a5b3f67f1df3701f1da54924afd4d6e4ba5917ec"}, -] - -[package.dependencies] -Werkzeug = ">=2.0.0" - -[[package]] -name = "pytest-timeout" -version = "2.4.0" -description = "pytest plugin to abort hanging tests" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2"}, - {file = "pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a"}, -] - -[package.dependencies] -pytest = ">=7.0.0" - -[[package]] -name = "pytest-xdist" -version = "3.8.0" -description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"}, - {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"}, -] - -[package.dependencies] -execnet = ">=2.1" -pytest = ">=7.0.0" - -[package.extras] -psutil = ["psutil (>=3.0)"] -setproctitle = ["setproctitle"] -testing = ["filelock"] - -[[package]] -name = "pyyaml" -version = "6.0.2" -description = "YAML parser and emitter for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, - {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, - {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, - {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, - {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, - {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, - {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, - {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, - {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, - {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, - {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, - {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, - {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, - {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, - {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, - {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, - {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, - {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, - {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, - {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, - {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, - {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, - {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, - {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, - {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, - {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, - {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, - {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, - {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, - {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, - {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, - {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, -] - -[[package]] -name = "regex" -version = "2025.7.34" -description = "Alternative regular expression module, to replace re." -optional = false -python-versions = ">=3.9" -files = [ - {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d856164d25e2b3b07b779bfed813eb4b6b6ce73c2fd818d46f47c1eb5cd79bd6"}, - {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d15a9da5fad793e35fb7be74eec450d968e05d2e294f3e0e77ab03fa7234a83"}, - {file = "regex-2025.7.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95b4639c77d414efa93c8de14ce3f7965a94d007e068a94f9d4997bb9bd9c81f"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7de1ceed5a5f84f342ba4a9f4ae589524adf9744b2ee61b5da884b5b659834"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02e5860a250cd350c4933cf376c3bc9cb28948e2c96a8bc042aee7b985cfa26f"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a5966220b9a1a88691282b7e4350e9599cf65780ca60d914a798cb791aa1177"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48fb045bbd4aab2418dc1ba2088a5e32de4bfe64e1457b948bb328a8dc2f1c2e"}, - {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:20ff8433fa45e131f7316594efe24d4679c5449c0ca69d91c2f9d21846fdf064"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c436fd1e95c04c19039668cfb548450a37c13f051e8659f40aed426e36b3765f"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0b85241d3cfb9f8a13cefdfbd58a2843f208f2ed2c88181bf84e22e0c7fc066d"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:075641c94126b064c65ab86e7e71fc3d63e7ff1bea1fb794f0773c97cdad3a03"}, - {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70645cad3407d103d1dbcb4841839d2946f7d36cf38acbd40120fee1682151e5"}, - {file = "regex-2025.7.34-cp310-cp310-win32.whl", hash = "sha256:3b836eb4a95526b263c2a3359308600bd95ce7848ebd3c29af0c37c4f9627cd3"}, - {file = "regex-2025.7.34-cp310-cp310-win_amd64.whl", hash = "sha256:cbfaa401d77334613cf434f723c7e8ba585df162be76474bccc53ae4e5520b3a"}, - {file = "regex-2025.7.34-cp310-cp310-win_arm64.whl", hash = "sha256:bca11d3c38a47c621769433c47f364b44e8043e0de8e482c5968b20ab90a3986"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da304313761b8500b8e175eb2040c4394a875837d5635f6256d6fa0377ad32c8"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:35e43ebf5b18cd751ea81455b19acfdec402e82fe0dc6143edfae4c5c4b3909a"}, - {file = "regex-2025.7.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96bbae4c616726f4661fe7bcad5952e10d25d3c51ddc388189d8864fbc1b3c68"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9feab78a1ffa4f2b1e27b1bcdaad36f48c2fed4870264ce32f52a393db093c78"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f14b36e6d4d07f1a5060f28ef3b3561c5d95eb0651741474ce4c0a4c56ba8719"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85c3a958ef8b3d5079c763477e1f09e89d13ad22198a37e9d7b26b4b17438b33"}, - {file = "regex-2025.7.34-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37555e4ae0b93358fa7c2d240a4291d4a4227cc7c607d8f85596cdb08ec0a083"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee38926f31f1aa61b0232a3a11b83461f7807661c062df9eb88769d86e6195c3"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a664291c31cae9c4a30589bd8bc2ebb56ef880c9c6264cb7643633831e606a4d"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f3e5c1e0925e77ec46ddc736b756a6da50d4df4ee3f69536ffb2373460e2dafd"}, - {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d428fc7731dcbb4e2ffe43aeb8f90775ad155e7db4347a639768bc6cd2df881a"}, - {file = "regex-2025.7.34-cp311-cp311-win32.whl", hash = "sha256:e154a7ee7fa18333ad90b20e16ef84daaeac61877c8ef942ec8dfa50dc38b7a1"}, - {file = "regex-2025.7.34-cp311-cp311-win_amd64.whl", hash = "sha256:24257953d5c1d6d3c129ab03414c07fc1a47833c9165d49b954190b2b7f21a1a"}, - {file = "regex-2025.7.34-cp311-cp311-win_arm64.whl", hash = "sha256:3157aa512b9e606586900888cd469a444f9b898ecb7f8931996cb715f77477f0"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7f7211a746aced993bef487de69307a38c5ddd79257d7be83f7b202cb59ddb50"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fb31080f2bd0681484b275461b202b5ad182f52c9ec606052020fe13eb13a72f"}, - {file = "regex-2025.7.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0200a5150c4cf61e407038f4b4d5cdad13e86345dac29ff9dab3d75d905cf130"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:739a74970e736df0773788377969c9fea3876c2fc13d0563f98e5503e5185f46"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4fef81b2f7ea6a2029161ed6dea9ae13834c28eb5a95b8771828194a026621e4"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea74cf81fe61a7e9d77989050d0089a927ab758c29dac4e8e1b6c06fccf3ebf0"}, - {file = "regex-2025.7.34-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e4636a7f3b65a5f340ed9ddf53585c42e3ff37101d383ed321bfe5660481744b"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cef962d7834437fe8d3da6f9bfc6f93f20f218266dcefec0560ed7765f5fe01"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:cbe1698e5b80298dbce8df4d8d1182279fbdaf1044e864cbc9d53c20e4a2be77"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:32b9f9bcf0f605eb094b08e8da72e44badabb63dde6b83bd530580b488d1c6da"}, - {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:524c868ba527eab4e8744a9287809579f54ae8c62fbf07d62aacd89f6026b282"}, - {file = "regex-2025.7.34-cp312-cp312-win32.whl", hash = "sha256:d600e58ee6d036081c89696d2bdd55d507498a7180df2e19945c6642fac59588"}, - {file = "regex-2025.7.34-cp312-cp312-win_amd64.whl", hash = "sha256:9a9ab52a466a9b4b91564437b36417b76033e8778e5af8f36be835d8cb370d62"}, - {file = "regex-2025.7.34-cp312-cp312-win_arm64.whl", hash = "sha256:c83aec91af9c6fbf7c743274fd952272403ad9a9db05fe9bfc9df8d12b45f176"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c3c9740a77aeef3f5e3aaab92403946a8d34437db930a0280e7e81ddcada61f5"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:69ed3bc611540f2ea70a4080f853741ec698be556b1df404599f8724690edbcd"}, - {file = "regex-2025.7.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d03c6f9dcd562c56527c42b8530aad93193e0b3254a588be1f2ed378cdfdea1b"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6164b1d99dee1dfad33f301f174d8139d4368a9fb50bf0a3603b2eaf579963ad"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1e4f4f62599b8142362f164ce776f19d79bdd21273e86920a7b604a4275b4f59"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72a26dcc6a59c057b292f39d41465d8233a10fd69121fa24f8f43ec6294e5415"}, - {file = "regex-2025.7.34-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5273fddf7a3e602695c92716c420c377599ed3c853ea669c1fe26218867002f"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c1844be23cd40135b3a5a4dd298e1e0c0cb36757364dd6cdc6025770363e06c1"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dde35e2afbbe2272f8abee3b9fe6772d9b5a07d82607b5788e8508974059925c"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f6e8e7af516a7549412ce57613e859c3be27d55341a894aacaa11703a4c31a"}, - {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:469142fb94a869beb25b5f18ea87646d21def10fbacb0bcb749224f3509476f0"}, - {file = "regex-2025.7.34-cp313-cp313-win32.whl", hash = "sha256:da7507d083ee33ccea1310447410c27ca11fb9ef18c95899ca57ff60a7e4d8f1"}, - {file = "regex-2025.7.34-cp313-cp313-win_amd64.whl", hash = "sha256:9d644de5520441e5f7e2db63aec2748948cc39ed4d7a87fd5db578ea4043d997"}, - {file = "regex-2025.7.34-cp313-cp313-win_arm64.whl", hash = "sha256:7bf1c5503a9f2cbd2f52d7e260acb3131b07b6273c470abb78568174fe6bde3f"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:8283afe7042d8270cecf27cca558873168e771183d4d593e3c5fe5f12402212a"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6c053f9647e3421dd2f5dff8172eb7b4eec129df9d1d2f7133a4386319b47435"}, - {file = "regex-2025.7.34-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a16dd56bbcb7d10e62861c3cd000290ddff28ea142ffb5eb3470f183628011ac"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69c593ff5a24c0d5c1112b0df9b09eae42b33c014bdca7022d6523b210b69f72"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98d0ce170fcde1a03b5df19c5650db22ab58af375aaa6ff07978a85c9f250f0e"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d72765a4bff8c43711d5b0f5b452991a9947853dfa471972169b3cc0ba1d0751"}, - {file = "regex-2025.7.34-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4494f8fd95a77eb434039ad8460e64d57baa0434f1395b7da44015bef650d0e4"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4f42b522259c66e918a0121a12429b2abcf696c6f967fa37bdc7b72e61469f98"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:aaef1f056d96a0a5d53ad47d019d5b4c66fe4be2da87016e0d43b7242599ffc7"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:656433e5b7dccc9bc0da6312da8eb897b81f5e560321ec413500e5367fcd5d47"}, - {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e91eb2c62c39705e17b4d42d4b86c4e86c884c0d15d9c5a47d0835f8387add8e"}, - {file = "regex-2025.7.34-cp314-cp314-win32.whl", hash = "sha256:f978ddfb6216028c8f1d6b0f7ef779949498b64117fc35a939022f67f810bdcb"}, - {file = "regex-2025.7.34-cp314-cp314-win_amd64.whl", hash = "sha256:4b7dc33b9b48fb37ead12ffc7bdb846ac72f99a80373c4da48f64b373a7abeae"}, - {file = "regex-2025.7.34-cp314-cp314-win_arm64.whl", hash = "sha256:4b8c4d39f451e64809912c82392933d80fe2e4a87eeef8859fcc5380d0173c64"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd5edc3f453de727af267c7909d083e19f6426fc9dd149e332b6034f2a5611e6"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa1cdfb8db96ef20137de5587954c812821966c3e8b48ffc871e22d7ec0a4938"}, - {file = "regex-2025.7.34-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89c9504fc96268e8e74b0283e548f53a80c421182a2007e3365805b74ceef936"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33be70d75fa05a904ee0dc43b650844e067d14c849df7e82ad673541cd465b5f"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57d25b6732ea93eeb1d090e8399b6235ca84a651b52d52d272ed37d3d2efa0f1"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:baf2fe122a3db1c0b9f161aa44463d8f7e33eeeda47bb0309923deb743a18276"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a764a83128af9c1a54be81485b34dca488cbcacefe1e1d543ef11fbace191e1"}, - {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7f663ccc4093877f55b51477522abd7299a14c5bb7626c5238599db6a0cb95d"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4913f52fbc7a744aaebf53acd8d3dc1b519e46ba481d4d7596de3c862e011ada"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:efac4db9e044d47fd3b6b0d40b6708f4dfa2d8131a5ac1d604064147c0f552fd"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7373afae7cfb716e3b8e15d0184510d518f9d21471f2d62918dbece85f2c588f"}, - {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9960d162f3fecf6af252534a1ae337e9c2e20d74469fed782903b24e2cc9d3d7"}, - {file = "regex-2025.7.34-cp39-cp39-win32.whl", hash = "sha256:95d538b10eb4621350a54bf14600cc80b514211d91a019dc74b8e23d2159ace5"}, - {file = "regex-2025.7.34-cp39-cp39-win_amd64.whl", hash = "sha256:f7f3071b5faa605b0ea51ec4bb3ea7257277446b053f4fd3ad02b1dcb4e64353"}, - {file = "regex-2025.7.34-cp39-cp39-win_arm64.whl", hash = "sha256:716a47515ba1d03f8e8a61c5013041c8c90f2e21f055203498105d7571b44531"}, - {file = "regex-2025.7.34.tar.gz", hash = "sha256:9ead9765217afd04a86822dfcd4ed2747dfe426e887da413b15ff0ac2457e21a"}, -] - -[[package]] -name = "requests" -version = "2.32.4" -description = "Python HTTP for Humans." -optional = false -python-versions = ">=3.8" -files = [ - {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, - {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, -] - -[package.dependencies] -certifi = ">=2017.4.17" -charset_normalizer = ">=2,<4" -idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<3" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] - -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -description = "A utility belt for advanced users of python-requests" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, - {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, -] - -[package.dependencies] -requests = ">=2.0.1,<3.0.0" - -[[package]] -name = "ruff" -version = "0.5.7" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, - {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, - {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, - {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, - {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, - {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, - {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, - {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, - {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.43" -description = "Database Abstraction Library" -optional = true -python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.43-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21ba7a08a4253c5825d1db389d4299f64a100ef9800e4624c8bf70d8f136e6ed"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11b9503fa6f8721bef9b8567730f664c5a5153d25e247aadc69247c4bc605227"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07097c0a1886c150ef2adba2ff7437e84d40c0f7dcb44a2c2b9c905ccfc6361c"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cdeff998cb294896a34e5b2f00e383e7c5c4ef3b4bfa375d9104723f15186443"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:bcf0724a62a5670e5718957e05c56ec2d6850267ea859f8ad2481838f889b42c"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-win32.whl", hash = "sha256:c697575d0e2b0a5f0433f679bda22f63873821d991e95a90e9e52aae517b2e32"}, - {file = "SQLAlchemy-2.0.43-cp37-cp37m-win_amd64.whl", hash = "sha256:d34c0f6dbefd2e816e8f341d0df7d4763d382e3f452423e752ffd1e213da2512"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70322986c0c699dca241418fcf18e637a4369e0ec50540a2b907b184c8bca069"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87accdbba88f33efa7b592dc2e8b2a9c2cdbca73db2f9d5c510790428c09c154"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c00e7845d2f692ebfc7d5e4ec1a3fd87698e4337d09e58d6749a16aedfdf8612"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:022e436a1cb39b13756cf93b48ecce7aa95382b9cfacceb80a7d263129dfd019"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c5e73ba0d76eefc82ec0219d2301cb33bfe5205ed7a2602523111e2e56ccbd20"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9c2e02f06c68092b875d5cbe4824238ab93a7fa35d9c38052c033f7ca45daa18"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-win32.whl", hash = "sha256:e7a903b5b45b0d9fa03ac6a331e1c1d6b7e0ab41c63b6217b3d10357b83c8b00"}, - {file = "sqlalchemy-2.0.43-cp310-cp310-win_amd64.whl", hash = "sha256:4bf0edb24c128b7be0c61cd17eef432e4bef507013292415f3fb7023f02b7d4b"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52d9b73b8fb3e9da34c2b31e6d99d60f5f99fd8c1225c9dad24aeb74a91e1d29"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f42f23e152e4545157fa367b2435a1ace7571cab016ca26038867eb7df2c3631"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fb1a8c5438e0c5ea51afe9c6564f951525795cf432bed0c028c1cb081276685"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db691fa174e8f7036afefe3061bc40ac2b770718be2862bfb03aabae09051aca"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2b3b4927d0bc03d02ad883f402d5de201dbc8894ac87d2e981e7d87430e60d"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d3d9b904ad4a6b175a2de0738248822f5ac410f52c2fd389ada0b5262d6a1e3"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-win32.whl", hash = "sha256:5cda6b51faff2639296e276591808c1726c4a77929cfaa0f514f30a5f6156921"}, - {file = "sqlalchemy-2.0.43-cp311-cp311-win_amd64.whl", hash = "sha256:c5d1730b25d9a07727d20ad74bc1039bbbb0a6ca24e6769861c1aa5bf2c4c4a8"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20d81fc2736509d7a2bd33292e489b056cbae543661bb7de7ce9f1c0cd6e7f24"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b9fc27650ff5a2c9d490c13c14906b918b0de1f8fcbb4c992712d8caf40e83"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6772e3ca8a43a65a37c88e2f3e2adfd511b0b1da37ef11ed78dea16aeae85bd9"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a113da919c25f7f641ffbd07fbc9077abd4b3b75097c888ab818f962707eb48"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4286a1139f14b7d70141c67a8ae1582fc2b69105f1b09d9573494eb4bb4b2687"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:529064085be2f4d8a6e5fab12d36ad44f1909a18848fcfbdb59cc6d4bbe48efe"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-win32.whl", hash = "sha256:b535d35dea8bbb8195e7e2b40059e2253acb2b7579b73c1b432a35363694641d"}, - {file = "sqlalchemy-2.0.43-cp312-cp312-win_amd64.whl", hash = "sha256:1c6d85327ca688dbae7e2b06d7d84cfe4f3fffa5b5f9e21bb6ce9d0e1a0e0e0a"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e7c08f57f75a2bb62d7ee80a89686a5e5669f199235c6d1dac75cd59374091c3"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14111d22c29efad445cd5021a70a8b42f7d9152d8ba7f73304c4d82460946aaa"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b27b56eb2f82653168cefe6cb8e970cdaf4f3a6cb2c5e3c3c1cf3158968ff9"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c5a9da957c56e43d72126a3f5845603da00e0293720b03bde0aacffcf2dc04f"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d79f9fdc9584ec83d1b3c75e9f4595c49017f5594fee1a2217117647225d738"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9df7126fd9db49e3a5a3999442cc67e9ee8971f3cb9644250107d7296cb2a164"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-win32.whl", hash = "sha256:7f1ac7828857fcedb0361b48b9ac4821469f7694089d15550bbcf9ab22564a1d"}, - {file = "sqlalchemy-2.0.43-cp313-cp313-win_amd64.whl", hash = "sha256:971ba928fcde01869361f504fcff3b7143b47d30de188b11c6357c0505824197"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4e6aeb2e0932f32950cf56a8b4813cb15ff792fc0c9b3752eaf067cfe298496a"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f964a05356f4bca4112e6334ed7c208174511bd56e6b8fc86dad4d024d4185"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46293c39252f93ea0910aababa8752ad628bcce3a10d3f260648dd472256983f"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:136063a68644eca9339d02e6693932116f6a8591ac013b0014479a1de664e40a"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6e2bf13d9256398d037fef09fd8bf9b0bf77876e22647d10761d35593b9ac547"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:44337823462291f17f994d64282a71c51d738fc9ef561bf265f1d0fd9116a782"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-win32.whl", hash = "sha256:13194276e69bb2af56198fef7909d48fd34820de01d9c92711a5fa45497cc7ed"}, - {file = "sqlalchemy-2.0.43-cp38-cp38-win_amd64.whl", hash = "sha256:334f41fa28de9f9be4b78445e68530da3c5fa054c907176460c81494f4ae1f5e"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb5c832cc30663aeaf5e39657712f4c4241ad1f638d487ef7216258f6d41fe7"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11f43c39b4b2ec755573952bbcc58d976779d482f6f832d7f33a8d869ae891bf"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:413391b2239db55be14fa4223034d7e13325a1812c8396ecd4f2c08696d5ccad"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c379e37b08c6c527181a397212346be39319fb64323741d23e46abd97a400d34"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:03d73ab2a37d9e40dec4984d1813d7878e01dbdc742448d44a7341b7a9f408c7"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8cee08f15d9e238ede42e9bbc1d6e7158d0ca4f176e4eab21f88ac819ae3bd7b"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-win32.whl", hash = "sha256:b3edaec7e8b6dc5cd94523c6df4f294014df67097c8217a89929c99975811414"}, - {file = "sqlalchemy-2.0.43-cp39-cp39-win_amd64.whl", hash = "sha256:227119ce0a89e762ecd882dc661e0aa677a690c914e358f0dd8932a2e8b2765b"}, - {file = "sqlalchemy-2.0.43-py3-none-any.whl", hash = "sha256:1681c21dd2ccee222c2fe0bef671d1aef7c504087c9c4e800371cfcc8ac966fc"}, - {file = "sqlalchemy-2.0.43.tar.gz", hash = "sha256:788bfcef6787a7764169cfe9859fe425bf44559619e1d9f56f5bddf2ebf6f417"}, -] - -[package.dependencies] -greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} -typing-extensions = ">=4.6.0" - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] -aioodbc = ["aioodbc", "greenlet (>=1)"] -aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (>=1)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "tenacity" -version = "9.1.2" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.9" -files = [ - {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, - {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - -[[package]] -name = "tiktoken" -version = "0.11.0" -description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -optional = false -python-versions = ">=3.9" -files = [ - {file = "tiktoken-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:8a9b517d6331d7103f8bef29ef93b3cca95fa766e293147fe7bacddf310d5917"}, - {file = "tiktoken-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b4ddb1849e6bf0afa6cc1c5d809fb980ca240a5fffe585a04e119519758788c0"}, - {file = "tiktoken-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10331d08b5ecf7a780b4fe4d0281328b23ab22cdb4ff65e68d56caeda9940ecc"}, - {file = "tiktoken-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b062c82300341dc87e0258c69f79bed725f87e753c21887aea90d272816be882"}, - {file = "tiktoken-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:195d84bec46169af3b1349a1495c151d37a0ff4cba73fd08282736be7f92cc6c"}, - {file = "tiktoken-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe91581b0ecdd8783ce8cb6e3178f2260a3912e8724d2f2d49552b98714641a1"}, - {file = "tiktoken-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ae374c46afadad0f501046db3da1b36cd4dfbfa52af23c998773682446097cf"}, - {file = "tiktoken-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25a512ff25dc6c85b58f5dd4f3d8c674dc05f96b02d66cdacf628d26a4e4866b"}, - {file = "tiktoken-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2130127471e293d385179c1f3f9cd445070c0772be73cdafb7cec9a3684c0458"}, - {file = "tiktoken-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e43022bf2c33f733ea9b54f6a3f6b4354b909f5a73388fb1b9347ca54a069c"}, - {file = "tiktoken-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:adb4e308eb64380dc70fa30493e21c93475eaa11669dea313b6bbf8210bfd013"}, - {file = "tiktoken-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ece6b76bfeeb61a125c44bbefdfccc279b5288e6007fbedc0d32bfec602df2f2"}, - {file = "tiktoken-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fd9e6b23e860973cf9526544e220b223c60badf5b62e80a33509d6d40e6c8f5d"}, - {file = "tiktoken-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a76d53cee2da71ee2731c9caa747398762bda19d7f92665e882fef229cb0b5b"}, - {file = "tiktoken-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ef72aab3ea240646e642413cb363b73869fed4e604dcfd69eec63dc54d603e8"}, - {file = "tiktoken-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f929255c705efec7a28bf515e29dc74220b2f07544a8c81b8d69e8efc4578bd"}, - {file = "tiktoken-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61f1d15822e4404953d499fd1dcc62817a12ae9fb1e4898033ec8fe3915fdf8e"}, - {file = "tiktoken-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:45927a71ab6643dfd3ef57d515a5db3d199137adf551f66453be098502838b0f"}, - {file = "tiktoken-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a5f3f25ffb152ee7fec78e90a5e5ea5b03b4ea240beed03305615847f7a6ace2"}, - {file = "tiktoken-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dc6e9ad16a2a75b4c4be7208055a1f707c9510541d94d9cc31f7fbdc8db41d8"}, - {file = "tiktoken-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a0517634d67a8a48fd4a4ad73930c3022629a85a217d256a6e9b8b47439d1e4"}, - {file = "tiktoken-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fb4effe60574675118b73c6fbfd3b5868e5d7a1f570d6cc0d18724b09ecf318"}, - {file = "tiktoken-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94f984c9831fd32688aef4348803b0905d4ae9c432303087bae370dc1381a2b8"}, - {file = "tiktoken-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2177ffda31dec4023356a441793fed82f7af5291120751dee4d696414f54db0c"}, - {file = "tiktoken-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:13220f12c9e82e399377e768640ddfe28bea962739cc3a869cad98f42c419a89"}, - {file = "tiktoken-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f2db627f5c74477c0404b4089fd8a28ae22fa982a6f7d9c7d4c305c375218f3"}, - {file = "tiktoken-0.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2302772f035dceb2bcf8e55a735e4604a0b51a6dd50f38218ff664d46ec43807"}, - {file = "tiktoken-0.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b977989afe44c94bcc50db1f76971bb26dca44218bd203ba95925ef56f8e7a"}, - {file = "tiktoken-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:669a1aa1ad6ebf1b3c26b45deb346f345da7680f845b5ea700bba45c20dea24c"}, - {file = "tiktoken-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:e363f33c720a055586f730c00e330df4c7ea0024bf1c83a8a9a9dbc054c4f304"}, - {file = "tiktoken-0.11.0.tar.gz", hash = "sha256:3c518641aee1c52247c2b97e74d8d07d780092af79d5911a6ab5e79359d9b06a"}, -] - -[package.dependencies] -regex = ">=2022.1.18" -requests = ">=2.26.0" - -[package.extras] -blobfile = ["blobfile (>=2)"] - -[[package]] -name = "tomli" -version = "2.2.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, - {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, - {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, - {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, - {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, - {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, - {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, - {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, - {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, - {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, - {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, - {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, - {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, - {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, - {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, - {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, - {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, - {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, -] - -[[package]] -name = "tqdm" -version = "4.67.1" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, - {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] -discord = ["requests"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - -[[package]] -name = "typing-extensions" -version = "4.14.1" -description = "Backported and Experimental Type Hints for Python 3.9+" -optional = false -python-versions = ">=3.9" -files = [ - {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, - {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, -] - -[[package]] -name = "typing-inspection" -version = "0.4.1" -description = "Runtime typing introspection tools" -optional = false -python-versions = ">=3.9" -files = [ - {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"}, - {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"}, -] - -[package.dependencies] -typing-extensions = ">=4.12.0" - -[[package]] -name = "urllib3" -version = "2.5.0" -description = "HTTP library with thread-safe connection pooling, file post, and more." -optional = false -python-versions = ">=3.9" -files = [ - {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, - {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, -] - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -h2 = ["h2 (>=4,<5)"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "virtualenv" -version = "20.34.0" -description = "Virtual Python Environment builder" -optional = false -python-versions = ">=3.8" -files = [ - {file = "virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026"}, - {file = "virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a"}, -] - -[package.dependencies] -distlib = ">=0.3.7,<1" -filelock = ">=3.12.2,<4" -platformdirs = ">=3.9.1,<5" -typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} - -[package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] -test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] - -[[package]] -name = "werkzeug" -version = "3.1.3" -description = "The comprehensive WSGI web application library." -optional = false -python-versions = ">=3.9" -files = [ - {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, - {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, -] - -[package.dependencies] -MarkupSafe = ">=2.1.1" - -[package.extras] -watchdog = ["watchdog (>=2.3)"] - -[[package]] -name = "wrapt" -version = "1.17.3" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.8" -files = [ - {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04"}, - {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2"}, - {file = "wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c"}, - {file = "wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775"}, - {file = "wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd"}, - {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05"}, - {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418"}, - {file = "wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390"}, - {file = "wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6"}, - {file = "wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"}, - {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"}, - {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"}, - {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"}, - {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"}, - {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"}, - {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"}, - {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"}, - {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"}, - {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"}, - {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"}, - {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"}, - {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"}, - {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"}, - {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"}, - {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"}, - {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77"}, - {file = "wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7"}, - {file = "wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277"}, - {file = "wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d"}, - {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa"}, - {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050"}, - {file = "wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8"}, - {file = "wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb"}, - {file = "wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235"}, - {file = "wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c"}, - {file = "wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b"}, - {file = "wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa"}, - {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7"}, - {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4"}, - {file = "wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10"}, - {file = "wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6"}, - {file = "wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067"}, - {file = "wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454"}, - {file = "wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e"}, - {file = "wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f"}, - {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056"}, - {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804"}, - {file = "wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977"}, - {file = "wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116"}, - {file = "wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a"}, - {file = "wrapt-1.17.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f"}, - {file = "wrapt-1.17.3-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00"}, - {file = "wrapt-1.17.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56"}, - {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5"}, - {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22"}, - {file = "wrapt-1.17.3-cp38-cp38-win32.whl", hash = "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c"}, - {file = "wrapt-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9"}, - {file = "wrapt-1.17.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d"}, - {file = "wrapt-1.17.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a"}, - {file = "wrapt-1.17.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139"}, - {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df"}, - {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b"}, - {file = "wrapt-1.17.3-cp39-cp39-win32.whl", hash = "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81"}, - {file = "wrapt-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f"}, - {file = "wrapt-1.17.3-cp39-cp39-win_arm64.whl", hash = "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f"}, - {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"}, - {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"}, -] - -[[package]] -name = "zipp" -version = "3.23.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.9" -files = [ - {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, - {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - -[[package]] -name = "zstandard" -version = "0.23.0" -description = "Zstandard bindings for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, - {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e"}, - {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0"}, - {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c"}, - {file = "zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813"}, - {file = "zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4"}, - {file = "zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e"}, - {file = "zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca"}, - {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78"}, - {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473"}, - {file = "zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160"}, - {file = "zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0"}, - {file = "zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094"}, - {file = "zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373"}, - {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90"}, - {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35"}, - {file = "zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d"}, - {file = "zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b"}, - {file = "zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9"}, - {file = "zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed"}, - {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057"}, - {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33"}, - {file = "zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd"}, - {file = "zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b"}, - {file = "zstandard-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc"}, - {file = "zstandard-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152"}, - {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b"}, - {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e"}, - {file = "zstandard-0.23.0-cp38-cp38-win32.whl", hash = "sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9"}, - {file = "zstandard-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f"}, - {file = "zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb"}, - {file = "zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58"}, - {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2"}, - {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5"}, - {file = "zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274"}, - {file = "zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58"}, - {file = "zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09"}, -] - -[package.dependencies] -cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\""} - -[package.extras] -cffi = ["cffi (>=1.11)"] - -[extras] -langchain = ["langchain"] -openai = ["openai"] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.9,<4.0" -content-hash = "d0356916b5c7adba0ed8ea357edb8adcde09269bd83613df67976cd93a246aa3" diff --git a/pyproject.toml b/pyproject.toml index 891c5751d..c49440761 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,48 +1,54 @@ -[tool.poetry] +[project] name = "langfuse" - version = "3.2.6" description = "A client library for accessing langfuse" -authors = ["langfuse "] -license = "MIT" +authors = [{ name = "langfuse", email = "developers@langfuse.com" }] +requires-python = ">=3.9,<4.0" readme = "README.md" +license = "MIT" +dependencies = [ + "httpx>=0.15.4,<1.0", + "pydantic>=1.10.7, <3.0", + "backoff>=1.10.0", + "wrapt~=1.14", + "packaging>=23.2,<26.0", + "requests>=2,<3", + "opentelemetry-api>=1.33.1,<2", + "opentelemetry-sdk>=1.33.1,<2", + "opentelemetry-exporter-otlp-proto-http>=1.33.1,<2", +] -[tool.poetry.dependencies] -python = ">=3.9,<4.0" -httpx = ">=0.15.4,<1.0" -pydantic = ">=1.10.7, <3.0" -backoff = ">=1.10.0" -openai = { version = ">=0.27.8", optional = true } -wrapt = "^1.14" -langchain = { version = ">=0.0.309", optional = true } -packaging = ">=23.2,<26.0" -requests = "^2" -opentelemetry-api = "^1.33.1" -opentelemetry-sdk = "^1.33.1" -opentelemetry-exporter-otlp-proto-http = "^1.33.1" +[project.optional-dependencies] +openai = ["openai>=0.27.8"] +langchain = ["langchain>=0.0.309"] -[tool.poetry.group.dev.dependencies] -pytest = ">=7.4,<9.0" -pytest-timeout = "^2.1.0" -pytest-xdist = "^3.3.1" -pre-commit = "^3.2.2" -pytest-asyncio = ">=0.21.1,<0.24.0" -pytest-httpserver = "^1.0.8" -ruff = ">=0.1.8,<0.6.0" -mypy = "^1.0.0" -langchain-openai = ">=0.0.5,<0.3" -langgraph = "^0.2.62" +[project.scripts] +release = "scripts.release:main" -[tool.poetry.group.docs.dependencies] -pdoc = "^14.4.0" +[dependency-groups] +dev = [ + "pytest>=7.4,<9.0", + "pytest-timeout>=2.1.0,<3", + "pytest-xdist>=3.3.1,<4", + "pre-commit>=3.2.2,<4", + "pytest-asyncio>=0.21.1,<0.24.0", + "pytest-httpserver>=1.0.8,<2", + "ruff>=0.1.8,<0.6.0", + "mypy>=1.0.0,<2", + "langchain-openai>=0.0.5,<0.3", + "langgraph>=0.2.62,<0.3", +] +docs = ["pdoc>=14.4.0,<15"] -[tool.poetry.extras] -openai = ["openai"] -langchain = ["langchain"] +[tool.uv] +default-groups = [ + "dev", + "docs", +] [build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" [tool.pytest.ini_options] log_cli = true @@ -104,6 +110,3 @@ module = [ "langfuse.api.client" ] ignore_errors = true - -[tool.poetry.scripts] -release = "scripts.release:main" diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py index 5b73662fb..4e7364fad 100644 --- a/tests/test_manual_graph_instrumentation.py +++ b/tests/test_manual_graph_instrumentation.py @@ -11,22 +11,22 @@ def test_observe_type_agent_instrumentation(): trace_name = f"type_based_graph_test_{create_uuid()}" - @observe(type="generation") + @observe(as_type="generation") def start_agent(): time.sleep(0.1) return {"status": "started", "data": "initial_data"} - @observe(type="retriever") + @observe(as_type="retriever") def process_agent(): time.sleep(0.1) return {"status": "processed", "data": "processed_data"} - @observe(type="tool") + @observe(as_type="tool") def tool_call(): time.sleep(0.1) return {"status": "intermediate", "data": "intermediate_data"} - @observe(type="generation") + @observe(as_type="generation") def end_agent(): time.sleep(0.1) return {"status": "completed", "data": "final_data"} @@ -66,7 +66,21 @@ def end_agent(): agent_observations = [ obs for obs in all_observations - if obs.type in ["agent", "tool", "retriever", "chain", "embedding", "AGENT", "TOOL", "RETRIEVER", "CHAIN", "EMBEDDING", "GENERATION", "generation"] + if obs.type + in [ + "agent", + "tool", + "retriever", + "chain", + "embedding", + "AGENT", + "TOOL", + "RETRIEVER", + "CHAIN", + "EMBEDDING", + "GENERATION", + "generation", + ] ] assert ( @@ -91,27 +105,27 @@ def test_observe_type_parallel_tool_execution(): trace_name = f"parallel_tools_test_{create_uuid()}" - @observe(type="agent") + @observe(as_type="agent") def start_agent(): time.sleep(0.05) return {"status": "tools_initiated", "tool_count": 3} - @observe(type="tool") + @observe(as_type="tool") def search_tool(): time.sleep(0.2) return {"tool": "search", "results": ["result1", "result2"]} - @observe(type="tool") + @observe(as_type="tool") def calculation_tool(): time.sleep(0.15) return {"tool": "calc", "result": 42} - @observe(type="tool") + @observe(as_type="tool") def api_tool(): time.sleep(0.1) return {"tool": "api", "data": {"status": "success"}} - @observe(type="agent") + @observe(as_type="agent") def end_agent(): time.sleep(0.05) return {"status": "completed", "summary": "all_tools_processed"} From 649da3a8241f467549f513cf8355e2b3c8a90a2d Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:37:28 +0200 Subject: [PATCH 23/66] restore --- poetry.lock | 2345 ++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 79 +- 2 files changed, 2383 insertions(+), 41 deletions(-) create mode 100644 poetry.lock diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 000000000..c3c1217e7 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,2345 @@ +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.10.0" +description = "High-level concurrency and networking framework on top of asyncio or Trio" +optional = false +python-versions = ">=3.9" +files = [ + {file = "anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1"}, + {file = "anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""} + +[package.extras] +trio = ["trio (>=0.26.1)"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = true +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "certifi" +version = "2025.8.3" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.7" +files = [ + {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, + {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "cfgv" +version = "3.4.0" +description = "Validate configuration and produce human readable error messages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.3" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +files = [ + {file = "charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f"}, + {file = "charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849"}, + {file = "charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37"}, + {file = "charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce"}, + {file = "charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce"}, + {file = "charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0f2be7e0cf7754b9a30eb01f4295cc3d4358a479843b31f328afd210e2c7598c"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c60e092517a73c632ec38e290eba714e9627abe9d301c8c8a12ec32c314a2a4b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:252098c8c7a873e17dd696ed98bbe91dbacd571da4b87df3736768efa7a792e4"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3653fad4fe3ed447a596ae8638b437f827234f01a8cd801842e43f3d0a6b281b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8999f965f922ae054125286faf9f11bc6932184b93011d138925a1773830bbe9"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95bfb53c211b57198bb91c46dd5a2d8018b3af446583aab40074bf7988401cb"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:5b413b0b1bfd94dbf4023ad6945889f374cd24e3f62de58d6bb102c4d9ae534a"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:b5e3b2d152e74e100a9e9573837aba24aab611d39428ded46f4e4022ea7d1942"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a2d08ac246bb48479170408d6c19f6385fa743e7157d716e144cad849b2dd94b"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-win32.whl", hash = "sha256:ec557499516fc90fd374bf2e32349a2887a876fbf162c160e3c01b6849eaf557"}, + {file = "charset_normalizer-3.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:5d8d01eac18c423815ed4f4a2ec3b439d654e55ee4ad610e153cf02faf67ea40"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:70bfc5f2c318afece2f5838ea5e4c3febada0be750fcf4775641052bbba14d05"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:23b6b24d74478dc833444cbd927c338349d6ae852ba53a0d02a2de1fce45b96e"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:34a7f768e3f985abdb42841e20e17b330ad3aaf4bb7e7aeeb73db2e70f077b99"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fb731e5deb0c7ef82d698b0f4c5bb724633ee2a489401594c5c88b02e6cb15f7"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:257f26fed7d7ff59921b78244f3cd93ed2af1800ff048c33f624c87475819dd7"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1ef99f0456d3d46a50945c98de1774da86f8e992ab5c77865ea8b8195341fc19"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2c322db9c8c89009a990ef07c3bcc9f011a3269bc06782f916cd3d9eed7c9312"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:511729f456829ef86ac41ca78c63a5cb55240ed23b4b737faca0eb1abb1c41bc"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88ab34806dea0671532d3f82d82b85e8fc23d7b2dd12fa837978dad9bb392a34"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-win32.whl", hash = "sha256:16a8770207946ac75703458e2c743631c79c59c5890c80011d536248f8eaa432"}, + {file = "charset_normalizer-3.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:d22dbedd33326a4a5190dd4fe9e9e693ef12160c77382d9e87919bce54f3d4ca"}, + {file = "charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a"}, + {file = "charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "distlib" +version = "0.4.0" +description = "Distribution utilities" +optional = false +python-versions = "*" +files = [ + {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"}, + {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"}, +] + +[[package]] +name = "distro" +version = "1.9.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, + {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""} + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "execnet" +version = "2.1.1" +description = "execnet: rapid multi-Python deployment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, + {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, +] + +[package.extras] +testing = ["hatch", "pre-commit", "pytest", "tox"] + +[[package]] +name = "filelock" +version = "3.18.0" +description = "A platform independent file lock." +optional = false +python-versions = ">=3.9" +files = [ + {file = "filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de"}, + {file = "filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.10)", "diff-cover (>=9.2.1)", "pytest (>=8.3.4)", "pytest-asyncio (>=0.25.2)", "pytest-cov (>=6)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.28.1)"] +typing = ["typing-extensions (>=4.12.2)"] + +[[package]] +name = "googleapis-common-protos" +version = "1.70.0" +description = "Common protobufs used in Google APIs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "googleapis_common_protos-1.70.0-py3-none-any.whl", hash = "sha256:b8bfcca8c25a2bb253e0e0b0adaf8c00773e5e6af6fd92397576680b807e0fd8"}, + {file = "googleapis_common_protos-1.70.0.tar.gz", hash = "sha256:0e1b44e0ea153e6594f9f394fef15193a68aaaea2d843f83e2742717ca753257"}, +] + +[package.dependencies] +protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0" + +[package.extras] +grpc = ["grpcio (>=1.44.0,<2.0.0)"] + +[[package]] +name = "greenlet" +version = "3.2.4" +description = "Lightweight in-process concurrent programming" +optional = true +python-versions = ">=3.9" +files = [ + {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"}, + {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"}, + {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"}, + {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"}, + {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"}, + {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"}, + {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"}, + {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"}, + {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"}, + {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"}, + {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"}, + {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"}, + {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"}, + {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"}, + {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"}, + {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"}, + {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"}, + {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"}, + {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"}, + {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"}, + {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"}, + {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"}, + {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"}, + {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"}, + {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"}, + {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"}, + {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"}, + {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"}, + {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"}, + {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil", "setuptools"] + +[[package]] +name = "h11" +version = "0.16.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.8" +files = [ + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, + {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.16" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "identify" +version = "2.6.13" +description = "File identification library for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "identify-2.6.13-py2.py3-none-any.whl", hash = "sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b"}, + {file = "identify-2.6.13.tar.gz", hash = "sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32"}, +] + +[package.extras] +license = ["ukkonen"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "importlib-metadata" +version = "8.7.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.9" +files = [ + {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, + {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib_resources (>=1.3)", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + +[[package]] +name = "iniconfig" +version = "2.1.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jiter" +version = "0.10.0" +description = "Fast iterable JSON parser." +optional = false +python-versions = ">=3.9" +files = [ + {file = "jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303"}, + {file = "jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf"}, + {file = "jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90"}, + {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0"}, + {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee"}, + {file = "jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4"}, + {file = "jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5"}, + {file = "jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978"}, + {file = "jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5"}, + {file = "jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606"}, + {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605"}, + {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5"}, + {file = "jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7"}, + {file = "jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812"}, + {file = "jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b"}, + {file = "jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a"}, + {file = "jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95"}, + {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea"}, + {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b"}, + {file = "jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01"}, + {file = "jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49"}, + {file = "jiter-0.10.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0588107ec8e11b6f5ef0e0d656fb2803ac6cf94a96b2b9fc675c0e3ab5e8644"}, + {file = "jiter-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cafc4628b616dc32530c20ee53d71589816cf385dd9449633e910d596b1f5c8a"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520ef6d981172693786a49ff5b09eda72a42e539f14788124a07530f785c3ad6"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:554dedfd05937f8fc45d17ebdf298fe7e0c77458232bcb73d9fbbf4c6455f5b3"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc299da7789deacf95f64052d97f75c16d4fc8c4c214a22bf8d859a4288a1c2"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5161e201172de298a8a1baad95eb85db4fb90e902353b1f6a41d64ea64644e25"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2227db6ba93cb3e2bf67c87e594adde0609f146344e8207e8730364db27041"}, + {file = "jiter-0.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15acb267ea5e2c64515574b06a8bf393fbfee6a50eb1673614aa45f4613c0cca"}, + {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:901b92f2e2947dc6dfcb52fd624453862e16665ea909a08398dde19c0731b7f4"}, + {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d0cb9a125d5a3ec971a094a845eadde2db0de85b33c9f13eb94a0c63d463879e"}, + {file = "jiter-0.10.0-cp313-cp313-win32.whl", hash = "sha256:48a403277ad1ee208fb930bdf91745e4d2d6e47253eedc96e2559d1e6527006d"}, + {file = "jiter-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:75f9eb72ecb640619c29bf714e78c9c46c9c4eaafd644bf78577ede459f330d4"}, + {file = "jiter-0.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:28ed2a4c05a1f32ef0e1d24c2611330219fed727dae01789f4a335617634b1ca"}, + {file = "jiter-0.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a4c418b1ec86a195f1ca69da8b23e8926c752b685af665ce30777233dfe070"}, + {file = "jiter-0.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d7bfed2fe1fe0e4dda6ef682cee888ba444b21e7a6553e03252e4feb6cf0adca"}, + {file = "jiter-0.10.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:5e9251a5e83fab8d87799d3e1a46cb4b7f2919b895c6f4483629ed2446f66522"}, + {file = "jiter-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:023aa0204126fe5b87ccbcd75c8a0d0261b9abdbbf46d55e7ae9f8e22424eeb8"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c189c4f1779c05f75fc17c0c1267594ed918996a231593a21a5ca5438445216"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15720084d90d1098ca0229352607cd68256c76991f6b374af96f36920eae13c4"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f2fb68e5f1cfee30e2b2a09549a00683e0fde4c6a2ab88c94072fc33cb7426"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce541693355fc6da424c08b7edf39a2895f58d6ea17d92cc2b168d20907dee12"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c50c40272e189d50006ad5c73883caabb73d4e9748a688b216e85a9a9ca3b9"}, + {file = "jiter-0.10.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa3402a2ff9815960e0372a47b75c76979d74402448509ccd49a275fa983ef8a"}, + {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:1956f934dca32d7bb647ea21d06d93ca40868b505c228556d3373cbd255ce853"}, + {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:fcedb049bdfc555e261d6f65a6abe1d5ad68825b7202ccb9692636c70fcced86"}, + {file = "jiter-0.10.0-cp314-cp314-win32.whl", hash = "sha256:ac509f7eccca54b2a29daeb516fb95b6f0bd0d0d8084efaf8ed5dfc7b9f0b357"}, + {file = "jiter-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ed975b83a2b8639356151cef5c0d597c68376fc4922b45d0eb384ac058cfa00"}, + {file = "jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5"}, + {file = "jiter-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bd6292a43c0fc09ce7c154ec0fa646a536b877d1e8f2f96c19707f65355b5a4d"}, + {file = "jiter-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39de429dcaeb6808d75ffe9effefe96a4903c6a4b376b2f6d08d77c1aaee2f18"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52ce124f13a7a616fad3bb723f2bfb537d78239d1f7f219566dc52b6f2a9e48d"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:166f3606f11920f9a1746b2eea84fa2c0a5d50fd313c38bdea4edc072000b0af"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28dcecbb4ba402916034fc14eba7709f250c4d24b0c43fc94d187ee0580af181"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86c5aa6910f9bebcc7bc4f8bc461aff68504388b43bfe5e5c0bd21efa33b52f4"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ceeb52d242b315d7f1f74b441b6a167f78cea801ad7c11c36da77ff2d42e8a28"}, + {file = "jiter-0.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff76d8887c8c8ee1e772274fcf8cc1071c2c58590d13e33bd12d02dc9a560397"}, + {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a9be4d0fa2b79f7222a88aa488bd89e2ae0a0a5b189462a12def6ece2faa45f1"}, + {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ab7fd8738094139b6c1ab1822d6f2000ebe41515c537235fd45dabe13ec9324"}, + {file = "jiter-0.10.0-cp39-cp39-win32.whl", hash = "sha256:5f51e048540dd27f204ff4a87f5d79294ea0aa3aa552aca34934588cf27023cf"}, + {file = "jiter-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b28302349dc65703a9e4ead16f163b1c339efffbe1049c30a44b001a2a4fff9"}, + {file = "jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "langchain" +version = "0.3.27" +description = "Building applications with LLMs through composability" +optional = true +python-versions = "<4.0,>=3.9" +files = [ + {file = "langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798"}, + {file = "langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} +langchain-core = ">=0.3.72,<1.0.0" +langchain-text-splitters = ">=0.3.9,<1.0.0" +langsmith = ">=0.1.17" +pydantic = ">=2.7.4,<3.0.0" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" + +[package.extras] +anthropic = ["langchain-anthropic"] +aws = ["langchain-aws"] +azure-ai = ["langchain-azure-ai"] +cohere = ["langchain-cohere"] +community = ["langchain-community"] +deepseek = ["langchain-deepseek"] +fireworks = ["langchain-fireworks"] +google-genai = ["langchain-google-genai"] +google-vertexai = ["langchain-google-vertexai"] +groq = ["langchain-groq"] +huggingface = ["langchain-huggingface"] +mistralai = ["langchain-mistralai"] +ollama = ["langchain-ollama"] +openai = ["langchain-openai"] +perplexity = ["langchain-perplexity"] +together = ["langchain-together"] +xai = ["langchain-xai"] + +[[package]] +name = "langchain-core" +version = "0.3.74" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.9" +files = [ + {file = "langchain_core-0.3.74-py3-none-any.whl", hash = "sha256:088338b5bc2f6a66892f9afc777992c24ee3188f41cbc603d09181e34a228ce7"}, + {file = "langchain_core-0.3.74.tar.gz", hash = "sha256:ff604441aeade942fbcc0a3860a592daba7671345230c2078ba2eb5f82b6ba76"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.3.45" +packaging = ">=23.2" +pydantic = ">=2.7.4" +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0" +typing-extensions = ">=4.7" + +[[package]] +name = "langchain-openai" +version = "0.2.14" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = "<4.0,>=3.9" +files = [ + {file = "langchain_openai-0.2.14-py3-none-any.whl", hash = "sha256:d232496662f79ece9a11caf7d798ba863e559c771bc366814f7688e0fe664fe8"}, + {file = "langchain_openai-0.2.14.tar.gz", hash = "sha256:7a514f309e356b182a337c0ed36ab3fbe34d9834a235a3b85cb7f91ae775d978"}, +] + +[package.dependencies] +langchain-core = ">=0.3.27,<0.4.0" +openai = ">=1.58.1,<2.0.0" +tiktoken = ">=0.7,<1" + +[[package]] +name = "langchain-text-splitters" +version = "0.3.9" +description = "LangChain text splitting utilities" +optional = true +python-versions = ">=3.9" +files = [ + {file = "langchain_text_splitters-0.3.9-py3-none-any.whl", hash = "sha256:cee0bb816211584ea79cc79927317c358543f40404bcfdd69e69ba3ccde54401"}, + {file = "langchain_text_splitters-0.3.9.tar.gz", hash = "sha256:7cd1e5a3aaf609979583eeca2eb34177622570b8fa8f586a605c6b1c34e7ebdb"}, +] + +[package.dependencies] +langchain-core = ">=0.3.72,<1.0.0" + +[[package]] +name = "langgraph" +version = "0.2.76" +description = "Building stateful, multi-actor applications with LLMs" +optional = false +python-versions = "<4.0,>=3.9.0" +files = [ + {file = "langgraph-0.2.76-py3-none-any.whl", hash = "sha256:076b8b5d2fc5a9761c46a7618430cfa5c978a8012257c43cbc127b27e0fd7872"}, + {file = "langgraph-0.2.76.tar.gz", hash = "sha256:688f8dcd9b6797ba78384599e0de944773000c75156ad1e186490e99e89fa5c0"}, +] + +[package.dependencies] +langchain-core = ">=0.2.43,<0.3.0 || >0.3.0,<0.3.1 || >0.3.1,<0.3.2 || >0.3.2,<0.3.3 || >0.3.3,<0.3.4 || >0.3.4,<0.3.5 || >0.3.5,<0.3.6 || >0.3.6,<0.3.7 || >0.3.7,<0.3.8 || >0.3.8,<0.3.9 || >0.3.9,<0.3.10 || >0.3.10,<0.3.11 || >0.3.11,<0.3.12 || >0.3.12,<0.3.13 || >0.3.13,<0.3.14 || >0.3.14,<0.3.15 || >0.3.15,<0.3.16 || >0.3.16,<0.3.17 || >0.3.17,<0.3.18 || >0.3.18,<0.3.19 || >0.3.19,<0.3.20 || >0.3.20,<0.3.21 || >0.3.21,<0.3.22 || >0.3.22,<0.4.0" +langgraph-checkpoint = ">=2.0.10,<3.0.0" +langgraph-sdk = ">=0.1.42,<0.2.0" + +[[package]] +name = "langgraph-checkpoint" +version = "2.1.1" +description = "Library with base interfaces for LangGraph checkpoint savers." +optional = false +python-versions = ">=3.9" +files = [ + {file = "langgraph_checkpoint-2.1.1-py3-none-any.whl", hash = "sha256:5a779134fd28134a9a83d078be4450bbf0e0c79fdf5e992549658899e6fc5ea7"}, + {file = "langgraph_checkpoint-2.1.1.tar.gz", hash = "sha256:72038c0f9e22260cb9bff1f3ebe5eb06d940b7ee5c1e4765019269d4f21cf92d"}, +] + +[package.dependencies] +langchain-core = ">=0.2.38" +ormsgpack = ">=1.10.0" + +[[package]] +name = "langgraph-sdk" +version = "0.1.74" +description = "SDK for interacting with LangGraph API" +optional = false +python-versions = ">=3.9" +files = [ + {file = "langgraph_sdk-0.1.74-py3-none-any.whl", hash = "sha256:3a265c3757fe0048adad4391d10486db63ef7aa5a2cbd22da22d4503554cb890"}, + {file = "langgraph_sdk-0.1.74.tar.gz", hash = "sha256:7450e0db5b226cc2e5328ca22c5968725873630ef47c4206a30707cb25dc3ad6"}, +] + +[package.dependencies] +httpx = ">=0.25.2" +orjson = ">=3.10.1" + +[[package]] +name = "langsmith" +version = "0.4.14" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = ">=3.9" +files = [ + {file = "langsmith-0.4.14-py3-none-any.whl", hash = "sha256:b6d070ac425196947d2a98126fb0e35f3b8c001a2e6e5b7049dd1c56f0767d0b"}, + {file = "langsmith-0.4.14.tar.gz", hash = "sha256:4d29c7a9c85b20ba813ab9c855407bccdf5eb4f397f512ffa89959b2a2cb83ed"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14", markers = "platform_python_implementation != \"PyPy\""} +packaging = ">=23.2" +pydantic = ">=1,<3" +requests = ">=2.0.0" +requests-toolbelt = ">=1.0.0" +zstandard = ">=0.23.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2)"] +openai-agents = ["openai-agents (>=0.0.3)"] +otel = ["opentelemetry-api (>=1.30.0)", "opentelemetry-exporter-otlp-proto-http (>=1.30.0)", "opentelemetry-sdk (>=1.30.0)"] +pytest = ["pytest (>=7.0.0)", "rich (>=13.9.4)", "vcrpy (>=7.0.0)"] +vcr = ["vcrpy (>=7.0.0)"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "mypy" +version = "1.17.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972"}, + {file = "mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7"}, + {file = "mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df"}, + {file = "mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390"}, + {file = "mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94"}, + {file = "mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b"}, + {file = "mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58"}, + {file = "mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5"}, + {file = "mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd"}, + {file = "mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b"}, + {file = "mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5"}, + {file = "mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b"}, + {file = "mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb"}, + {file = "mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403"}, + {file = "mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056"}, + {file = "mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341"}, + {file = "mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb"}, + {file = "mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19"}, + {file = "mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7"}, + {file = "mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81"}, + {file = "mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6"}, + {file = "mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849"}, + {file = "mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14"}, + {file = "mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a"}, + {file = "mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733"}, + {file = "mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd"}, + {file = "mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0"}, + {file = "mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a"}, + {file = "mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91"}, + {file = "mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed"}, + {file = "mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9"}, + {file = "mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99"}, + {file = "mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8"}, + {file = "mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8"}, + {file = "mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259"}, + {file = "mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d"}, + {file = "mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9"}, + {file = "mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01"}, +] + +[package.dependencies] +mypy_extensions = ">=1.0.0" +pathspec = ">=0.9.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing_extensions = ">=4.6.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +faster-cache = ["orjson"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, + {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +description = "Node.js virtual environment builder" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + +[[package]] +name = "openai" +version = "1.99.9" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.8" +files = [ + {file = "openai-1.99.9-py3-none-any.whl", hash = "sha256:9dbcdb425553bae1ac5d947147bebbd630d91bbfc7788394d4c4f3a35682ab3a"}, + {file = "openai-1.99.9.tar.gz", hash = "sha256:f2082d155b1ad22e83247c3de3958eb4255b20ccf4a1de2e6681b6957b554e92"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +jiter = ">=0.4.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.11,<5" + +[package.extras] +aiohttp = ["aiohttp", "httpx-aiohttp (>=0.1.8)"] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] +realtime = ["websockets (>=13,<16)"] +voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"] + +[[package]] +name = "opentelemetry-api" +version = "1.36.0" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_api-1.36.0-py3-none-any.whl", hash = "sha256:02f20bcacf666e1333b6b1f04e647dc1d5111f86b8e510238fcc56d7762cda8c"}, + {file = "opentelemetry_api-1.36.0.tar.gz", hash = "sha256:9a72572b9c416d004d492cbc6e61962c0501eaf945ece9b5a0f56597d8348aa0"}, +] + +[package.dependencies] +importlib-metadata = ">=6.0,<8.8.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-exporter-otlp-proto-common" +version = "1.36.0" +description = "OpenTelemetry Protobuf encoding" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_exporter_otlp_proto_common-1.36.0-py3-none-any.whl", hash = "sha256:0fc002a6ed63eac235ada9aa7056e5492e9a71728214a61745f6ad04b923f840"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.36.0.tar.gz", hash = "sha256:6c496ccbcbe26b04653cecadd92f73659b814c6e3579af157d8716e5f9f25cbf"}, +] + +[package.dependencies] +opentelemetry-proto = "1.36.0" + +[[package]] +name = "opentelemetry-exporter-otlp-proto-http" +version = "1.36.0" +description = "OpenTelemetry Collector Protobuf over HTTP Exporter" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_exporter_otlp_proto_http-1.36.0-py3-none-any.whl", hash = "sha256:3d769f68e2267e7abe4527f70deb6f598f40be3ea34c6adc35789bea94a32902"}, + {file = "opentelemetry_exporter_otlp_proto_http-1.36.0.tar.gz", hash = "sha256:dd3637f72f774b9fc9608ab1ac479f8b44d09b6fb5b2f3df68a24ad1da7d356e"}, +] + +[package.dependencies] +googleapis-common-protos = ">=1.52,<2.0" +opentelemetry-api = ">=1.15,<2.0" +opentelemetry-exporter-otlp-proto-common = "1.36.0" +opentelemetry-proto = "1.36.0" +opentelemetry-sdk = ">=1.36.0,<1.37.0" +requests = ">=2.7,<3.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-proto" +version = "1.36.0" +description = "OpenTelemetry Python Proto" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_proto-1.36.0-py3-none-any.whl", hash = "sha256:151b3bf73a09f94afc658497cf77d45a565606f62ce0c17acb08cd9937ca206e"}, + {file = "opentelemetry_proto-1.36.0.tar.gz", hash = "sha256:0f10b3c72f74c91e0764a5ec88fd8f1c368ea5d9c64639fb455e2854ef87dd2f"}, +] + +[package.dependencies] +protobuf = ">=5.0,<7.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.36.0" +description = "OpenTelemetry Python SDK" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_sdk-1.36.0-py3-none-any.whl", hash = "sha256:19fe048b42e98c5c1ffe85b569b7073576ad4ce0bcb6e9b4c6a39e890a6c45fb"}, + {file = "opentelemetry_sdk-1.36.0.tar.gz", hash = "sha256:19c8c81599f51b71670661ff7495c905d8fdf6976e41622d5245b791b06fa581"}, +] + +[package.dependencies] +opentelemetry-api = "1.36.0" +opentelemetry-semantic-conventions = "0.57b0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.57b0" +description = "OpenTelemetry Semantic Conventions" +optional = false +python-versions = ">=3.9" +files = [ + {file = "opentelemetry_semantic_conventions-0.57b0-py3-none-any.whl", hash = "sha256:757f7e76293294f124c827e514c2a3144f191ef175b069ce8d1211e1e38e9e78"}, + {file = "opentelemetry_semantic_conventions-0.57b0.tar.gz", hash = "sha256:609a4a79c7891b4620d64c7aac6898f872d790d75f22019913a660756f27ff32"}, +] + +[package.dependencies] +opentelemetry-api = "1.36.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "orjson" +version = "3.11.2" +description = "" +optional = false +python-versions = ">=3.9" +files = [ + {file = "orjson-3.11.2-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:d6b8a78c33496230a60dc9487118c284c15ebdf6724386057239641e1eb69761"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc04036eeae11ad4180d1f7b5faddb5dab1dee49ecd147cd431523869514873b"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9c04325839c5754c253ff301cee8aaed7442d974860a44447bb3be785c411c27"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32769e04cd7fdc4a59854376211145a1bbbc0aea5e9d6c9755d3d3c301d7c0df"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff285d14917ea1408a821786e3677c5261fa6095277410409c694b8e7720ae0"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2662f908114864b63ff75ffe6ffacf996418dd6cc25e02a72ad4bda81b1ec45a"}, + {file = "orjson-3.11.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab463cf5d08ad6623a4dac1badd20e88a5eb4b840050c4812c782e3149fe2334"}, + {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:64414241bde943cbf3c00d45fcb5223dca6d9210148ba984aae6b5d63294502b"}, + {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:7773e71c0ae8c9660192ff144a3d69df89725325e3d0b6a6bb2c50e5ebaf9b84"}, + {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:652ca14e283b13ece35bf3a86503c25592f294dbcfc5bb91b20a9c9a62a3d4be"}, + {file = "orjson-3.11.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:26e99e98df8990ecfe3772bbdd7361f602149715c2cbc82e61af89bfad9528a4"}, + {file = "orjson-3.11.2-cp310-cp310-win32.whl", hash = "sha256:5814313b3e75a2be7fe6c7958201c16c4560e21a813dbad25920752cecd6ad66"}, + {file = "orjson-3.11.2-cp310-cp310-win_amd64.whl", hash = "sha256:dc471ce2225ab4c42ca672f70600d46a8b8e28e8d4e536088c1ccdb1d22b35ce"}, + {file = "orjson-3.11.2-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:888b64ef7eaeeff63f773881929434a5834a6a140a63ad45183d59287f07fc6a"}, + {file = "orjson-3.11.2-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:83387cc8b26c9fa0ae34d1ea8861a7ae6cff8fb3e346ab53e987d085315a728e"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7e35f003692c216d7ee901b6b916b5734d6fc4180fcaa44c52081f974c08e17"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4a0a4c29ae90b11d0c00bcc31533854d89f77bde2649ec602f512a7e16e00640"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:585d712b1880f68370108bc5534a257b561672d1592fae54938738fe7f6f1e33"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d08e342a7143f8a7c11f1c4033efe81acbd3c98c68ba1b26b96080396019701f"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c0f84fc50398773a702732c87cd622737bf11c0721e6db3041ac7802a686fb"}, + {file = "orjson-3.11.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:140f84e3c8d4c142575898c91e3981000afebf0333df753a90b3435d349a5fe5"}, + {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96304a2b7235e0f3f2d9363ddccdbfb027d27338722fe469fe656832a017602e"}, + {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:3d7612bb227d5d9582f1f50a60bd55c64618fc22c4a32825d233a4f2771a428a"}, + {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a134587d18fe493befc2defffef2a8d27cfcada5696cb7234de54a21903ae89a"}, + {file = "orjson-3.11.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0b84455e60c4bc12c1e4cbaa5cfc1acdc7775a9da9cec040e17232f4b05458bd"}, + {file = "orjson-3.11.2-cp311-cp311-win32.whl", hash = "sha256:f0660efeac223f0731a70884e6914a5f04d613b5ae500744c43f7bf7b78f00f9"}, + {file = "orjson-3.11.2-cp311-cp311-win_amd64.whl", hash = "sha256:955811c8405251d9e09cbe8606ad8fdef49a451bcf5520095a5ed38c669223d8"}, + {file = "orjson-3.11.2-cp311-cp311-win_arm64.whl", hash = "sha256:2e4d423a6f838552e3a6d9ec734b729f61f88b1124fd697eab82805ea1a2a97d"}, + {file = "orjson-3.11.2-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:901d80d349d8452162b3aa1afb82cec5bee79a10550660bc21311cc61a4c5486"}, + {file = "orjson-3.11.2-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:cf3bd3967a360e87ee14ed82cb258b7f18c710dacf3822fb0042a14313a673a1"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26693dde66910078229a943e80eeb99fdce6cd2c26277dc80ead9f3ab97d2131"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4ad4c8acb50a28211c33fc7ef85ddf5cb18d4636a5205fd3fa2dce0411a0e30c"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:994181e7f1725bb5f2d481d7d228738e0743b16bf319ca85c29369c65913df14"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbb79a0476393c07656b69c8e763c3cc925fa8e1d9e9b7d1f626901bb5025448"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:191ed27a1dddb305083d8716af413d7219f40ec1d4c9b0e977453b4db0d6fb6c"}, + {file = "orjson-3.11.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0afb89f16f07220183fd00f5f297328ed0a68d8722ad1b0c8dcd95b12bc82804"}, + {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6ab6e6b4e93b1573a026b6ec16fca9541354dd58e514b62c558b58554ae04307"}, + {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:9cb23527efb61fb75527df55d20ee47989c4ee34e01a9c98ee9ede232abf6219"}, + {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a4dd1268e4035af21b8a09e4adf2e61f87ee7bf63b86d7bb0a237ac03fad5b45"}, + {file = "orjson-3.11.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ff8b155b145eaf5a9d94d2c476fbe18d6021de93cf36c2ae2c8c5b775763f14e"}, + {file = "orjson-3.11.2-cp312-cp312-win32.whl", hash = "sha256:ae3bb10279d57872f9aba68c9931aa71ed3b295fa880f25e68da79e79453f46e"}, + {file = "orjson-3.11.2-cp312-cp312-win_amd64.whl", hash = "sha256:d026e1967239ec11a2559b4146a61d13914504b396f74510a1c4d6b19dfd8732"}, + {file = "orjson-3.11.2-cp312-cp312-win_arm64.whl", hash = "sha256:59f8d5ad08602711af9589375be98477d70e1d102645430b5a7985fdbf613b36"}, + {file = "orjson-3.11.2-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a079fdba7062ab396380eeedb589afb81dc6683f07f528a03b6f7aae420a0219"}, + {file = "orjson-3.11.2-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:6a5f62ebbc530bb8bb4b1ead103647b395ba523559149b91a6c545f7cd4110ad"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7df6c7b8b0931feb3420b72838c3e2ba98c228f7aa60d461bc050cf4ca5f7b2"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6f59dfea7da1fced6e782bb3699718088b1036cb361f36c6e4dd843c5111aefe"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edf49146520fef308c31aa4c45b9925fd9c7584645caca7c0c4217d7900214ae"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50995bbeb5d41a32ad15e023305807f561ac5dcd9bd41a12c8d8d1d2c83e44e6"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cc42960515076eb639b705f105712b658c525863d89a1704d984b929b0577d1"}, + {file = "orjson-3.11.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c56777cab2a7b2a8ea687fedafb84b3d7fdafae382165c31a2adf88634c432fa"}, + {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:07349e88025b9b5c783077bf7a9f401ffbfb07fd20e86ec6fc5b7432c28c2c5e"}, + {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:45841fbb79c96441a8c58aa29ffef570c5df9af91f0f7a9572e5505e12412f15"}, + {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:13d8d8db6cd8d89d4d4e0f4161acbbb373a4d2a4929e862d1d2119de4aa324ac"}, + {file = "orjson-3.11.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51da1ee2178ed09c00d09c1b953e45846bbc16b6420965eb7a913ba209f606d8"}, + {file = "orjson-3.11.2-cp313-cp313-win32.whl", hash = "sha256:51dc033df2e4a4c91c0ba4f43247de99b3cbf42ee7a42ee2b2b2f76c8b2f2cb5"}, + {file = "orjson-3.11.2-cp313-cp313-win_amd64.whl", hash = "sha256:29d91d74942b7436f29b5d1ed9bcfc3f6ef2d4f7c4997616509004679936650d"}, + {file = "orjson-3.11.2-cp313-cp313-win_arm64.whl", hash = "sha256:4ca4fb5ac21cd1e48028d4f708b1bb13e39c42d45614befd2ead004a8bba8535"}, + {file = "orjson-3.11.2-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3dcba7101ea6a8d4ef060746c0f2e7aa8e2453a1012083e1ecce9726d7554cb7"}, + {file = "orjson-3.11.2-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:15d17bdb76a142e1f55d91913e012e6e6769659daa6bfef3ef93f11083137e81"}, + {file = "orjson-3.11.2-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:53c9e81768c69d4b66b8876ec3c8e431c6e13477186d0db1089d82622bccd19f"}, + {file = "orjson-3.11.2-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:d4f13af59a7b84c1ca6b8a7ab70d608f61f7c44f9740cd42409e6ae7b6c8d8b7"}, + {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bde64aa469b5ee46cc960ed241fae3721d6a8801dacb2ca3466547a2535951e4"}, + {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b5ca86300aeb383c8fa759566aca065878d3d98c3389d769b43f0a2e84d52c5f"}, + {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:24e32a558ebed73a6a71c8f1cbc163a7dd5132da5270ff3d8eeb727f4b6d1bc7"}, + {file = "orjson-3.11.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e36319a5d15b97e4344110517450396845cc6789aed712b1fbf83c1bd95792f6"}, + {file = "orjson-3.11.2-cp314-cp314-win32.whl", hash = "sha256:40193ada63fab25e35703454d65b6afc71dbc65f20041cb46c6d91709141ef7f"}, + {file = "orjson-3.11.2-cp314-cp314-win_amd64.whl", hash = "sha256:7c8ac5f6b682d3494217085cf04dadae66efee45349ad4ee2a1da3c97e2305a8"}, + {file = "orjson-3.11.2-cp314-cp314-win_arm64.whl", hash = "sha256:21cf261e8e79284242e4cb1e5924df16ae28255184aafeff19be1405f6d33f67"}, + {file = "orjson-3.11.2-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:957f10c7b5bce3d3f2ad577f3b307c784f5dabafcce3b836229c269c11841c86"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a669e31ab8eb466c9142ac7a4be2bb2758ad236a31ef40dcd4cf8774ab40f33"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:adedf7d887416c51ad49de3c53b111887e0b63db36c6eb9f846a8430952303d8"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ad8873979659ad98fc56377b9c5b93eb8059bf01e6412f7abf7dbb3d637a991"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9482ef83b2bf796157566dd2d2742a8a1e377045fe6065fa67acb1cb1d21d9a3"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73cee7867c1fcbd1cc5b6688b3e13db067f968889242955780123a68b3d03316"}, + {file = "orjson-3.11.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:465166773265f3cc25db10199f5d11c81898a309e26a2481acf33ddbec433fda"}, + {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:bc000190a7b1d2d8e36cba990b3209a1e15c0efb6c7750e87f8bead01afc0d46"}, + {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:df3fdd8efa842ccbb81135d6f58a73512f11dba02ed08d9466261c2e9417af4e"}, + {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3dacfc621be3079ec69e0d4cb32e3764067726e0ef5a5576428f68b6dc85b4f6"}, + {file = "orjson-3.11.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9fdff73a029cde5f4a1cf5ec9dbc6acab98c9ddd69f5580c2b3f02ce43ba9f9f"}, + {file = "orjson-3.11.2-cp39-cp39-win32.whl", hash = "sha256:b1efbdc479c6451138c3733e415b4d0e16526644e54e2f3689f699c4cda303bf"}, + {file = "orjson-3.11.2-cp39-cp39-win_amd64.whl", hash = "sha256:c9ec0cc0d4308cad1e38a1ee23b64567e2ff364c2a3fe3d6cbc69cf911c45712"}, + {file = "orjson-3.11.2.tar.gz", hash = "sha256:91bdcf5e69a8fd8e8bdb3de32b31ff01d2bd60c1e8d5fe7d5afabdcf19920309"}, +] + +[[package]] +name = "ormsgpack" +version = "1.10.0" +description = "Fast, correct Python msgpack library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.9" +files = [ + {file = "ormsgpack-1.10.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8a52c7ce7659459f3dc8dec9fd6a6c76f855a0a7e2b61f26090982ac10b95216"}, + {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:060f67fe927582f4f63a1260726d019204b72f460cf20930e6c925a1d129f373"}, + {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7058ef6092f995561bf9f71d6c9a4da867b6cc69d2e94cb80184f579a3ceed5"}, + {file = "ormsgpack-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10f6f3509c1b0e51b15552d314b1d409321718122e90653122ce4b997f01453a"}, + {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c1edafd5c72b863b1f875ec31c529f09c872a5ff6fe473b9dfaf188ccc3227"}, + {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c780b44107a547a9e9327270f802fa4d6b0f6667c9c03c3338c0ce812259a0f7"}, + {file = "ormsgpack-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:137aab0d5cdb6df702da950a80405eb2b7038509585e32b4e16289604ac7cb84"}, + {file = "ormsgpack-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:3e666cb63030538fa5cd74b1e40cb55b6fdb6e2981f024997a288bf138ebad07"}, + {file = "ormsgpack-1.10.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4bb7df307e17b36cbf7959cd642c47a7f2046ae19408c564e437f0ec323a7775"}, + {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8817ae439c671779e1127ee62f0ac67afdeaeeacb5f0db45703168aa74a2e4af"}, + {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f345f81e852035d80232e64374d3a104139d60f8f43c6c5eade35c4bac5590e"}, + {file = "ormsgpack-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21de648a1c7ef692bdd287fb08f047bd5371d7462504c0a7ae1553c39fee35e3"}, + {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3a7d844ae9cbf2112c16086dd931b2acefce14cefd163c57db161170c2bfa22b"}, + {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4d80585403d86d7f800cf3d0aafac1189b403941e84e90dd5102bb2b92bf9d5"}, + {file = "ormsgpack-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:da1de515a87e339e78a3ccf60e39f5fb740edac3e9e82d3c3d209e217a13ac08"}, + {file = "ormsgpack-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:57c4601812684024132cbb32c17a7d4bb46ffc7daf2fddf5b697391c2c4f142a"}, + {file = "ormsgpack-1.10.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:4e159d50cd4064d7540e2bc6a0ab66eab70b0cc40c618b485324ee17037527c0"}, + {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eeb47c85f3a866e29279d801115b554af0fefc409e2ed8aa90aabfa77efe5cc6"}, + {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c28249574934534c9bd5dce5485c52f21bcea0ee44d13ece3def6e3d2c3798b5"}, + {file = "ormsgpack-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1957dcadbb16e6a981cd3f9caef9faf4c2df1125e2a1b702ee8236a55837ce07"}, + {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3b29412558c740bf6bac156727aa85ac67f9952cd6f071318f29ee72e1a76044"}, + {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6933f350c2041ec189fe739f0ba7d6117c8772f5bc81f45b97697a84d03020dd"}, + {file = "ormsgpack-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a86de06d368fcc2e58b79dece527dc8ca831e0e8b9cec5d6e633d2777ec93d0"}, + {file = "ormsgpack-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:35fa9f81e5b9a0dab42e09a73f7339ecffdb978d6dbf9deb2ecf1e9fc7808722"}, + {file = "ormsgpack-1.10.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d816d45175a878993b7372bd5408e0f3ec5a40f48e2d5b9d8f1cc5d31b61f1f"}, + {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a90345ccb058de0f35262893751c603b6376b05f02be2b6f6b7e05d9dd6d5643"}, + {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144b5e88f1999433e54db9d637bae6fe21e935888be4e3ac3daecd8260bd454e"}, + {file = "ormsgpack-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2190b352509d012915921cca76267db136cd026ddee42f1b0d9624613cc7058c"}, + {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:86fd9c1737eaba43d3bb2730add9c9e8b5fbed85282433705dd1b1e88ea7e6fb"}, + {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:33afe143a7b61ad21bb60109a86bb4e87fec70ef35db76b89c65b17e32da7935"}, + {file = "ormsgpack-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f23d45080846a7b90feabec0d330a9cc1863dc956728412e4f7986c80ab3a668"}, + {file = "ormsgpack-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:534d18acb805c75e5fba09598bf40abe1851c853247e61dda0c01f772234da69"}, + {file = "ormsgpack-1.10.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efdb25cf6d54085f7ae557268d59fd2d956f1a09a340856e282d2960fe929f32"}, + {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddfcb30d4b1be2439836249d675f297947f4fb8efcd3eeb6fd83021d773cadc4"}, + {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee0944b6ccfd880beb1ca29f9442a774683c366f17f4207f8b81c5e24cadb453"}, + {file = "ormsgpack-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35cdff6a0d3ba04e40a751129763c3b9b57a602c02944138e4b760ec99ae80a1"}, + {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:599ccdabc19c618ef5de6e6f2e7f5d48c1f531a625fa6772313b8515bc710681"}, + {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:bf46f57da9364bd5eefd92365c1b78797f56c6f780581eecd60cd7b367f9b4d3"}, + {file = "ormsgpack-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b796f64fdf823dedb1e35436a4a6f889cf78b1aa42d3097c66e5adfd8c3bd72d"}, + {file = "ormsgpack-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:106253ac9dc08520951e556b3c270220fcb8b4fef0d30b71eedac4befa4de749"}, + {file = "ormsgpack-1.10.0.tar.gz", hash = "sha256:7f7a27efd67ef22d7182ec3b7fa7e9d147c3ad9be2a24656b23c989077e08b16"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + +[[package]] +name = "pdoc" +version = "14.7.0" +description = "API Documentation for Python Projects" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pdoc-14.7.0-py3-none-any.whl", hash = "sha256:72377a907efc6b2c5b3c56b717ef34f11d93621dced3b663f3aede0b844c0ad2"}, + {file = "pdoc-14.7.0.tar.gz", hash = "sha256:2d28af9c0acc39180744ad0543e4bbc3223ecba0d1302db315ec521c51f71f93"}, +] + +[package.dependencies] +Jinja2 = ">=2.11.0" +MarkupSafe = "*" +pygments = ">=2.12.0" + +[package.extras] +dev = ["hypothesis", "mypy", "pdoc-pyo3-sample-library (==1.0.11)", "pygments (>=2.14.0)", "pytest", "pytest-cov", "pytest-timeout", "ruff", "tox", "types-pygments"] + +[[package]] +name = "platformdirs" +version = "4.3.8" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +optional = false +python-versions = ">=3.9" +files = [ + {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, + {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, +] + +[package.extras] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.1.3)", "sphinx-autodoc-typehints (>=3)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.4)", "pytest-cov (>=6)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.14.1)"] + +[[package]] +name = "pluggy" +version = "1.6.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"}, + {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["coverage", "pytest", "pytest-benchmark"] + +[[package]] +name = "pre-commit" +version = "3.8.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +optional = false +python-versions = ">=3.9" +files = [ + {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"}, + {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"}, +] + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +virtualenv = ">=20.10.0" + +[[package]] +name = "protobuf" +version = "6.31.1" +description = "" +optional = false +python-versions = ">=3.9" +files = [ + {file = "protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9"}, + {file = "protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447"}, + {file = "protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402"}, + {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39"}, + {file = "protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6"}, + {file = "protobuf-6.31.1-cp39-cp39-win32.whl", hash = "sha256:0414e3aa5a5f3ff423828e1e6a6e907d6c65c1d5b7e6e975793d5590bdeecc16"}, + {file = "protobuf-6.31.1-cp39-cp39-win_amd64.whl", hash = "sha256:8764cf4587791e7564051b35524b72844f845ad0bb011704c3736cce762d8fe9"}, + {file = "protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e"}, + {file = "protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.11.7" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"}, + {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.33.2" +typing-extensions = ">=4.12.2" +typing-inspection = ">=0.4.0" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata"] + +[[package]] +name = "pydantic-core" +version = "2.33.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, + {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pygments" +version = "2.19.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, + {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pytest" +version = "8.4.1" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7"}, + {file = "pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c"}, +] + +[package.dependencies] +colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""} +iniconfig = ">=1" +packaging = ">=20" +pluggy = ">=1.5,<2" +pygments = ">=2.7.2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "0.23.8" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, + {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, +] + +[package.dependencies] +pytest = ">=7.0.0,<9" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] + +[[package]] +name = "pytest-httpserver" +version = "1.1.3" +description = "pytest-httpserver is a httpserver for pytest" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pytest_httpserver-1.1.3-py3-none-any.whl", hash = "sha256:5f84757810233e19e2bb5287f3826a71c97a3740abe3a363af9155c0f82fdbb9"}, + {file = "pytest_httpserver-1.1.3.tar.gz", hash = "sha256:af819d6b533f84b4680b9416a5b3f67f1df3701f1da54924afd4d6e4ba5917ec"}, +] + +[package.dependencies] +Werkzeug = ">=2.0.0" + +[[package]] +name = "pytest-timeout" +version = "2.4.0" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2"}, + {file = "pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[[package]] +name = "pytest-xdist" +version = "3.8.0" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"}, + {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"}, +] + +[package.dependencies] +execnet = ">=2.1" +pytest = ">=7.0.0" + +[package.extras] +psutil = ["psutil (>=3.0)"] +setproctitle = ["setproctitle"] +testing = ["filelock"] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "regex" +version = "2025.7.34" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.9" +files = [ + {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d856164d25e2b3b07b779bfed813eb4b6b6ce73c2fd818d46f47c1eb5cd79bd6"}, + {file = "regex-2025.7.34-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d15a9da5fad793e35fb7be74eec450d968e05d2e294f3e0e77ab03fa7234a83"}, + {file = "regex-2025.7.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95b4639c77d414efa93c8de14ce3f7965a94d007e068a94f9d4997bb9bd9c81f"}, + {file = "regex-2025.7.34-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7de1ceed5a5f84f342ba4a9f4ae589524adf9744b2ee61b5da884b5b659834"}, + {file = "regex-2025.7.34-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:02e5860a250cd350c4933cf376c3bc9cb28948e2c96a8bc042aee7b985cfa26f"}, + {file = "regex-2025.7.34-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a5966220b9a1a88691282b7e4350e9599cf65780ca60d914a798cb791aa1177"}, + {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48fb045bbd4aab2418dc1ba2088a5e32de4bfe64e1457b948bb328a8dc2f1c2e"}, + {file = "regex-2025.7.34-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:20ff8433fa45e131f7316594efe24d4679c5449c0ca69d91c2f9d21846fdf064"}, + {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c436fd1e95c04c19039668cfb548450a37c13f051e8659f40aed426e36b3765f"}, + {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:0b85241d3cfb9f8a13cefdfbd58a2843f208f2ed2c88181bf84e22e0c7fc066d"}, + {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:075641c94126b064c65ab86e7e71fc3d63e7ff1bea1fb794f0773c97cdad3a03"}, + {file = "regex-2025.7.34-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:70645cad3407d103d1dbcb4841839d2946f7d36cf38acbd40120fee1682151e5"}, + {file = "regex-2025.7.34-cp310-cp310-win32.whl", hash = "sha256:3b836eb4a95526b263c2a3359308600bd95ce7848ebd3c29af0c37c4f9627cd3"}, + {file = "regex-2025.7.34-cp310-cp310-win_amd64.whl", hash = "sha256:cbfaa401d77334613cf434f723c7e8ba585df162be76474bccc53ae4e5520b3a"}, + {file = "regex-2025.7.34-cp310-cp310-win_arm64.whl", hash = "sha256:bca11d3c38a47c621769433c47f364b44e8043e0de8e482c5968b20ab90a3986"}, + {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da304313761b8500b8e175eb2040c4394a875837d5635f6256d6fa0377ad32c8"}, + {file = "regex-2025.7.34-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:35e43ebf5b18cd751ea81455b19acfdec402e82fe0dc6143edfae4c5c4b3909a"}, + {file = "regex-2025.7.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96bbae4c616726f4661fe7bcad5952e10d25d3c51ddc388189d8864fbc1b3c68"}, + {file = "regex-2025.7.34-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9feab78a1ffa4f2b1e27b1bcdaad36f48c2fed4870264ce32f52a393db093c78"}, + {file = "regex-2025.7.34-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f14b36e6d4d07f1a5060f28ef3b3561c5d95eb0651741474ce4c0a4c56ba8719"}, + {file = "regex-2025.7.34-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85c3a958ef8b3d5079c763477e1f09e89d13ad22198a37e9d7b26b4b17438b33"}, + {file = "regex-2025.7.34-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:37555e4ae0b93358fa7c2d240a4291d4a4227cc7c607d8f85596cdb08ec0a083"}, + {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ee38926f31f1aa61b0232a3a11b83461f7807661c062df9eb88769d86e6195c3"}, + {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a664291c31cae9c4a30589bd8bc2ebb56ef880c9c6264cb7643633831e606a4d"}, + {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f3e5c1e0925e77ec46ddc736b756a6da50d4df4ee3f69536ffb2373460e2dafd"}, + {file = "regex-2025.7.34-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d428fc7731dcbb4e2ffe43aeb8f90775ad155e7db4347a639768bc6cd2df881a"}, + {file = "regex-2025.7.34-cp311-cp311-win32.whl", hash = "sha256:e154a7ee7fa18333ad90b20e16ef84daaeac61877c8ef942ec8dfa50dc38b7a1"}, + {file = "regex-2025.7.34-cp311-cp311-win_amd64.whl", hash = "sha256:24257953d5c1d6d3c129ab03414c07fc1a47833c9165d49b954190b2b7f21a1a"}, + {file = "regex-2025.7.34-cp311-cp311-win_arm64.whl", hash = "sha256:3157aa512b9e606586900888cd469a444f9b898ecb7f8931996cb715f77477f0"}, + {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7f7211a746aced993bef487de69307a38c5ddd79257d7be83f7b202cb59ddb50"}, + {file = "regex-2025.7.34-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fb31080f2bd0681484b275461b202b5ad182f52c9ec606052020fe13eb13a72f"}, + {file = "regex-2025.7.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0200a5150c4cf61e407038f4b4d5cdad13e86345dac29ff9dab3d75d905cf130"}, + {file = "regex-2025.7.34-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:739a74970e736df0773788377969c9fea3876c2fc13d0563f98e5503e5185f46"}, + {file = "regex-2025.7.34-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4fef81b2f7ea6a2029161ed6dea9ae13834c28eb5a95b8771828194a026621e4"}, + {file = "regex-2025.7.34-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea74cf81fe61a7e9d77989050d0089a927ab758c29dac4e8e1b6c06fccf3ebf0"}, + {file = "regex-2025.7.34-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e4636a7f3b65a5f340ed9ddf53585c42e3ff37101d383ed321bfe5660481744b"}, + {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6cef962d7834437fe8d3da6f9bfc6f93f20f218266dcefec0560ed7765f5fe01"}, + {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:cbe1698e5b80298dbce8df4d8d1182279fbdaf1044e864cbc9d53c20e4a2be77"}, + {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:32b9f9bcf0f605eb094b08e8da72e44badabb63dde6b83bd530580b488d1c6da"}, + {file = "regex-2025.7.34-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:524c868ba527eab4e8744a9287809579f54ae8c62fbf07d62aacd89f6026b282"}, + {file = "regex-2025.7.34-cp312-cp312-win32.whl", hash = "sha256:d600e58ee6d036081c89696d2bdd55d507498a7180df2e19945c6642fac59588"}, + {file = "regex-2025.7.34-cp312-cp312-win_amd64.whl", hash = "sha256:9a9ab52a466a9b4b91564437b36417b76033e8778e5af8f36be835d8cb370d62"}, + {file = "regex-2025.7.34-cp312-cp312-win_arm64.whl", hash = "sha256:c83aec91af9c6fbf7c743274fd952272403ad9a9db05fe9bfc9df8d12b45f176"}, + {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c3c9740a77aeef3f5e3aaab92403946a8d34437db930a0280e7e81ddcada61f5"}, + {file = "regex-2025.7.34-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:69ed3bc611540f2ea70a4080f853741ec698be556b1df404599f8724690edbcd"}, + {file = "regex-2025.7.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d03c6f9dcd562c56527c42b8530aad93193e0b3254a588be1f2ed378cdfdea1b"}, + {file = "regex-2025.7.34-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6164b1d99dee1dfad33f301f174d8139d4368a9fb50bf0a3603b2eaf579963ad"}, + {file = "regex-2025.7.34-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1e4f4f62599b8142362f164ce776f19d79bdd21273e86920a7b604a4275b4f59"}, + {file = "regex-2025.7.34-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72a26dcc6a59c057b292f39d41465d8233a10fd69121fa24f8f43ec6294e5415"}, + {file = "regex-2025.7.34-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5273fddf7a3e602695c92716c420c377599ed3c853ea669c1fe26218867002f"}, + {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c1844be23cd40135b3a5a4dd298e1e0c0cb36757364dd6cdc6025770363e06c1"}, + {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dde35e2afbbe2272f8abee3b9fe6772d9b5a07d82607b5788e8508974059925c"}, + {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f6e8e7af516a7549412ce57613e859c3be27d55341a894aacaa11703a4c31a"}, + {file = "regex-2025.7.34-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:469142fb94a869beb25b5f18ea87646d21def10fbacb0bcb749224f3509476f0"}, + {file = "regex-2025.7.34-cp313-cp313-win32.whl", hash = "sha256:da7507d083ee33ccea1310447410c27ca11fb9ef18c95899ca57ff60a7e4d8f1"}, + {file = "regex-2025.7.34-cp313-cp313-win_amd64.whl", hash = "sha256:9d644de5520441e5f7e2db63aec2748948cc39ed4d7a87fd5db578ea4043d997"}, + {file = "regex-2025.7.34-cp313-cp313-win_arm64.whl", hash = "sha256:7bf1c5503a9f2cbd2f52d7e260acb3131b07b6273c470abb78568174fe6bde3f"}, + {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:8283afe7042d8270cecf27cca558873168e771183d4d593e3c5fe5f12402212a"}, + {file = "regex-2025.7.34-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6c053f9647e3421dd2f5dff8172eb7b4eec129df9d1d2f7133a4386319b47435"}, + {file = "regex-2025.7.34-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a16dd56bbcb7d10e62861c3cd000290ddff28ea142ffb5eb3470f183628011ac"}, + {file = "regex-2025.7.34-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69c593ff5a24c0d5c1112b0df9b09eae42b33c014bdca7022d6523b210b69f72"}, + {file = "regex-2025.7.34-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98d0ce170fcde1a03b5df19c5650db22ab58af375aaa6ff07978a85c9f250f0e"}, + {file = "regex-2025.7.34-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d72765a4bff8c43711d5b0f5b452991a9947853dfa471972169b3cc0ba1d0751"}, + {file = "regex-2025.7.34-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4494f8fd95a77eb434039ad8460e64d57baa0434f1395b7da44015bef650d0e4"}, + {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4f42b522259c66e918a0121a12429b2abcf696c6f967fa37bdc7b72e61469f98"}, + {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:aaef1f056d96a0a5d53ad47d019d5b4c66fe4be2da87016e0d43b7242599ffc7"}, + {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:656433e5b7dccc9bc0da6312da8eb897b81f5e560321ec413500e5367fcd5d47"}, + {file = "regex-2025.7.34-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e91eb2c62c39705e17b4d42d4b86c4e86c884c0d15d9c5a47d0835f8387add8e"}, + {file = "regex-2025.7.34-cp314-cp314-win32.whl", hash = "sha256:f978ddfb6216028c8f1d6b0f7ef779949498b64117fc35a939022f67f810bdcb"}, + {file = "regex-2025.7.34-cp314-cp314-win_amd64.whl", hash = "sha256:4b7dc33b9b48fb37ead12ffc7bdb846ac72f99a80373c4da48f64b373a7abeae"}, + {file = "regex-2025.7.34-cp314-cp314-win_arm64.whl", hash = "sha256:4b8c4d39f451e64809912c82392933d80fe2e4a87eeef8859fcc5380d0173c64"}, + {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd5edc3f453de727af267c7909d083e19f6426fc9dd149e332b6034f2a5611e6"}, + {file = "regex-2025.7.34-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa1cdfb8db96ef20137de5587954c812821966c3e8b48ffc871e22d7ec0a4938"}, + {file = "regex-2025.7.34-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:89c9504fc96268e8e74b0283e548f53a80c421182a2007e3365805b74ceef936"}, + {file = "regex-2025.7.34-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33be70d75fa05a904ee0dc43b650844e067d14c849df7e82ad673541cd465b5f"}, + {file = "regex-2025.7.34-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57d25b6732ea93eeb1d090e8399b6235ca84a651b52d52d272ed37d3d2efa0f1"}, + {file = "regex-2025.7.34-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:baf2fe122a3db1c0b9f161aa44463d8f7e33eeeda47bb0309923deb743a18276"}, + {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a764a83128af9c1a54be81485b34dca488cbcacefe1e1d543ef11fbace191e1"}, + {file = "regex-2025.7.34-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c7f663ccc4093877f55b51477522abd7299a14c5bb7626c5238599db6a0cb95d"}, + {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4913f52fbc7a744aaebf53acd8d3dc1b519e46ba481d4d7596de3c862e011ada"}, + {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:efac4db9e044d47fd3b6b0d40b6708f4dfa2d8131a5ac1d604064147c0f552fd"}, + {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:7373afae7cfb716e3b8e15d0184510d518f9d21471f2d62918dbece85f2c588f"}, + {file = "regex-2025.7.34-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9960d162f3fecf6af252534a1ae337e9c2e20d74469fed782903b24e2cc9d3d7"}, + {file = "regex-2025.7.34-cp39-cp39-win32.whl", hash = "sha256:95d538b10eb4621350a54bf14600cc80b514211d91a019dc74b8e23d2159ace5"}, + {file = "regex-2025.7.34-cp39-cp39-win_amd64.whl", hash = "sha256:f7f3071b5faa605b0ea51ec4bb3ea7257277446b053f4fd3ad02b1dcb4e64353"}, + {file = "regex-2025.7.34-cp39-cp39-win_arm64.whl", hash = "sha256:716a47515ba1d03f8e8a61c5013041c8c90f2e21f055203498105d7571b44531"}, + {file = "regex-2025.7.34.tar.gz", hash = "sha256:9ead9765217afd04a86822dfcd4ed2747dfe426e887da413b15ff0ac2457e21a"}, +] + +[[package]] +name = "requests" +version = "2.32.4" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, + {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset_normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "ruff" +version = "0.5.7" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a"}, + {file = "ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be"}, + {file = "ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb"}, + {file = "ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5"}, + {file = "ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e"}, + {file = "ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a"}, + {file = "ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3"}, + {file = "ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4"}, + {file = "ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.43" +description = "Database Abstraction Library" +optional = true +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.43-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21ba7a08a4253c5825d1db389d4299f64a100ef9800e4624c8bf70d8f136e6ed"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11b9503fa6f8721bef9b8567730f664c5a5153d25e247aadc69247c4bc605227"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07097c0a1886c150ef2adba2ff7437e84d40c0f7dcb44a2c2b9c905ccfc6361c"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cdeff998cb294896a34e5b2f00e383e7c5c4ef3b4bfa375d9104723f15186443"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:bcf0724a62a5670e5718957e05c56ec2d6850267ea859f8ad2481838f889b42c"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-win32.whl", hash = "sha256:c697575d0e2b0a5f0433f679bda22f63873821d991e95a90e9e52aae517b2e32"}, + {file = "SQLAlchemy-2.0.43-cp37-cp37m-win_amd64.whl", hash = "sha256:d34c0f6dbefd2e816e8f341d0df7d4763d382e3f452423e752ffd1e213da2512"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70322986c0c699dca241418fcf18e637a4369e0ec50540a2b907b184c8bca069"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87accdbba88f33efa7b592dc2e8b2a9c2cdbca73db2f9d5c510790428c09c154"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c00e7845d2f692ebfc7d5e4ec1a3fd87698e4337d09e58d6749a16aedfdf8612"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:022e436a1cb39b13756cf93b48ecce7aa95382b9cfacceb80a7d263129dfd019"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c5e73ba0d76eefc82ec0219d2301cb33bfe5205ed7a2602523111e2e56ccbd20"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9c2e02f06c68092b875d5cbe4824238ab93a7fa35d9c38052c033f7ca45daa18"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-win32.whl", hash = "sha256:e7a903b5b45b0d9fa03ac6a331e1c1d6b7e0ab41c63b6217b3d10357b83c8b00"}, + {file = "sqlalchemy-2.0.43-cp310-cp310-win_amd64.whl", hash = "sha256:4bf0edb24c128b7be0c61cd17eef432e4bef507013292415f3fb7023f02b7d4b"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:52d9b73b8fb3e9da34c2b31e6d99d60f5f99fd8c1225c9dad24aeb74a91e1d29"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f42f23e152e4545157fa367b2435a1ace7571cab016ca26038867eb7df2c3631"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fb1a8c5438e0c5ea51afe9c6564f951525795cf432bed0c028c1cb081276685"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db691fa174e8f7036afefe3061bc40ac2b770718be2862bfb03aabae09051aca"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2b3b4927d0bc03d02ad883f402d5de201dbc8894ac87d2e981e7d87430e60d"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d3d9b904ad4a6b175a2de0738248822f5ac410f52c2fd389ada0b5262d6a1e3"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-win32.whl", hash = "sha256:5cda6b51faff2639296e276591808c1726c4a77929cfaa0f514f30a5f6156921"}, + {file = "sqlalchemy-2.0.43-cp311-cp311-win_amd64.whl", hash = "sha256:c5d1730b25d9a07727d20ad74bc1039bbbb0a6ca24e6769861c1aa5bf2c4c4a8"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:20d81fc2736509d7a2bd33292e489b056cbae543661bb7de7ce9f1c0cd6e7f24"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b9fc27650ff5a2c9d490c13c14906b918b0de1f8fcbb4c992712d8caf40e83"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6772e3ca8a43a65a37c88e2f3e2adfd511b0b1da37ef11ed78dea16aeae85bd9"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a113da919c25f7f641ffbd07fbc9077abd4b3b75097c888ab818f962707eb48"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4286a1139f14b7d70141c67a8ae1582fc2b69105f1b09d9573494eb4bb4b2687"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:529064085be2f4d8a6e5fab12d36ad44f1909a18848fcfbdb59cc6d4bbe48efe"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-win32.whl", hash = "sha256:b535d35dea8bbb8195e7e2b40059e2253acb2b7579b73c1b432a35363694641d"}, + {file = "sqlalchemy-2.0.43-cp312-cp312-win_amd64.whl", hash = "sha256:1c6d85327ca688dbae7e2b06d7d84cfe4f3fffa5b5f9e21bb6ce9d0e1a0e0e0a"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e7c08f57f75a2bb62d7ee80a89686a5e5669f199235c6d1dac75cd59374091c3"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:14111d22c29efad445cd5021a70a8b42f7d9152d8ba7f73304c4d82460946aaa"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b27b56eb2f82653168cefe6cb8e970cdaf4f3a6cb2c5e3c3c1cf3158968ff9"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c5a9da957c56e43d72126a3f5845603da00e0293720b03bde0aacffcf2dc04f"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d79f9fdc9584ec83d1b3c75e9f4595c49017f5594fee1a2217117647225d738"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9df7126fd9db49e3a5a3999442cc67e9ee8971f3cb9644250107d7296cb2a164"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-win32.whl", hash = "sha256:7f1ac7828857fcedb0361b48b9ac4821469f7694089d15550bbcf9ab22564a1d"}, + {file = "sqlalchemy-2.0.43-cp313-cp313-win_amd64.whl", hash = "sha256:971ba928fcde01869361f504fcff3b7143b47d30de188b11c6357c0505824197"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4e6aeb2e0932f32950cf56a8b4813cb15ff792fc0c9b3752eaf067cfe298496a"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f964a05356f4bca4112e6334ed7c208174511bd56e6b8fc86dad4d024d4185"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46293c39252f93ea0910aababa8752ad628bcce3a10d3f260648dd472256983f"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:136063a68644eca9339d02e6693932116f6a8591ac013b0014479a1de664e40a"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6e2bf13d9256398d037fef09fd8bf9b0bf77876e22647d10761d35593b9ac547"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:44337823462291f17f994d64282a71c51d738fc9ef561bf265f1d0fd9116a782"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-win32.whl", hash = "sha256:13194276e69bb2af56198fef7909d48fd34820de01d9c92711a5fa45497cc7ed"}, + {file = "sqlalchemy-2.0.43-cp38-cp38-win_amd64.whl", hash = "sha256:334f41fa28de9f9be4b78445e68530da3c5fa054c907176460c81494f4ae1f5e"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ceb5c832cc30663aeaf5e39657712f4c4241ad1f638d487ef7216258f6d41fe7"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:11f43c39b4b2ec755573952bbcc58d976779d482f6f832d7f33a8d869ae891bf"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:413391b2239db55be14fa4223034d7e13325a1812c8396ecd4f2c08696d5ccad"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c379e37b08c6c527181a397212346be39319fb64323741d23e46abd97a400d34"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:03d73ab2a37d9e40dec4984d1813d7878e01dbdc742448d44a7341b7a9f408c7"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8cee08f15d9e238ede42e9bbc1d6e7158d0ca4f176e4eab21f88ac819ae3bd7b"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-win32.whl", hash = "sha256:b3edaec7e8b6dc5cd94523c6df4f294014df67097c8217a89929c99975811414"}, + {file = "sqlalchemy-2.0.43-cp39-cp39-win_amd64.whl", hash = "sha256:227119ce0a89e762ecd882dc661e0aa677a690c914e358f0dd8932a2e8b2765b"}, + {file = "sqlalchemy-2.0.43-py3-none-any.whl", hash = "sha256:1681c21dd2ccee222c2fe0bef671d1aef7c504087c9c4e800371cfcc8ac966fc"}, + {file = "sqlalchemy-2.0.43.tar.gz", hash = "sha256:788bfcef6787a7764169cfe9859fe425bf44559619e1d9f56f5bddf2ebf6f417"}, +] + +[package.dependencies] +greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] +aioodbc = ["aioodbc", "greenlet (>=1)"] +aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (>=1)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "tenacity" +version = "9.1.2" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.9" +files = [ + {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, + {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "tiktoken" +version = "0.11.0" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.9" +files = [ + {file = "tiktoken-0.11.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:8a9b517d6331d7103f8bef29ef93b3cca95fa766e293147fe7bacddf310d5917"}, + {file = "tiktoken-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b4ddb1849e6bf0afa6cc1c5d809fb980ca240a5fffe585a04e119519758788c0"}, + {file = "tiktoken-0.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10331d08b5ecf7a780b4fe4d0281328b23ab22cdb4ff65e68d56caeda9940ecc"}, + {file = "tiktoken-0.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b062c82300341dc87e0258c69f79bed725f87e753c21887aea90d272816be882"}, + {file = "tiktoken-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:195d84bec46169af3b1349a1495c151d37a0ff4cba73fd08282736be7f92cc6c"}, + {file = "tiktoken-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe91581b0ecdd8783ce8cb6e3178f2260a3912e8724d2f2d49552b98714641a1"}, + {file = "tiktoken-0.11.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4ae374c46afadad0f501046db3da1b36cd4dfbfa52af23c998773682446097cf"}, + {file = "tiktoken-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25a512ff25dc6c85b58f5dd4f3d8c674dc05f96b02d66cdacf628d26a4e4866b"}, + {file = "tiktoken-0.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2130127471e293d385179c1f3f9cd445070c0772be73cdafb7cec9a3684c0458"}, + {file = "tiktoken-0.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e43022bf2c33f733ea9b54f6a3f6b4354b909f5a73388fb1b9347ca54a069c"}, + {file = "tiktoken-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:adb4e308eb64380dc70fa30493e21c93475eaa11669dea313b6bbf8210bfd013"}, + {file = "tiktoken-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:ece6b76bfeeb61a125c44bbefdfccc279b5288e6007fbedc0d32bfec602df2f2"}, + {file = "tiktoken-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fd9e6b23e860973cf9526544e220b223c60badf5b62e80a33509d6d40e6c8f5d"}, + {file = "tiktoken-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6a76d53cee2da71ee2731c9caa747398762bda19d7f92665e882fef229cb0b5b"}, + {file = "tiktoken-0.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ef72aab3ea240646e642413cb363b73869fed4e604dcfd69eec63dc54d603e8"}, + {file = "tiktoken-0.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f929255c705efec7a28bf515e29dc74220b2f07544a8c81b8d69e8efc4578bd"}, + {file = "tiktoken-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61f1d15822e4404953d499fd1dcc62817a12ae9fb1e4898033ec8fe3915fdf8e"}, + {file = "tiktoken-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:45927a71ab6643dfd3ef57d515a5db3d199137adf551f66453be098502838b0f"}, + {file = "tiktoken-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a5f3f25ffb152ee7fec78e90a5e5ea5b03b4ea240beed03305615847f7a6ace2"}, + {file = "tiktoken-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dc6e9ad16a2a75b4c4be7208055a1f707c9510541d94d9cc31f7fbdc8db41d8"}, + {file = "tiktoken-0.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a0517634d67a8a48fd4a4ad73930c3022629a85a217d256a6e9b8b47439d1e4"}, + {file = "tiktoken-0.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fb4effe60574675118b73c6fbfd3b5868e5d7a1f570d6cc0d18724b09ecf318"}, + {file = "tiktoken-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94f984c9831fd32688aef4348803b0905d4ae9c432303087bae370dc1381a2b8"}, + {file = "tiktoken-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:2177ffda31dec4023356a441793fed82f7af5291120751dee4d696414f54db0c"}, + {file = "tiktoken-0.11.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:13220f12c9e82e399377e768640ddfe28bea962739cc3a869cad98f42c419a89"}, + {file = "tiktoken-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f2db627f5c74477c0404b4089fd8a28ae22fa982a6f7d9c7d4c305c375218f3"}, + {file = "tiktoken-0.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2302772f035dceb2bcf8e55a735e4604a0b51a6dd50f38218ff664d46ec43807"}, + {file = "tiktoken-0.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b977989afe44c94bcc50db1f76971bb26dca44218bd203ba95925ef56f8e7a"}, + {file = "tiktoken-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:669a1aa1ad6ebf1b3c26b45deb346f345da7680f845b5ea700bba45c20dea24c"}, + {file = "tiktoken-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:e363f33c720a055586f730c00e330df4c7ea0024bf1c83a8a9a9dbc054c4f304"}, + {file = "tiktoken-0.11.0.tar.gz", hash = "sha256:3c518641aee1c52247c2b97e74d8d07d780092af79d5911a6ab5e79359d9b06a"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"] +discord = ["requests"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "typing-extensions" +version = "4.14.1" +description = "Backported and Experimental Type Hints for Python 3.9+" +optional = false +python-versions = ">=3.9" +files = [ + {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, + {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, +] + +[[package]] +name = "typing-inspection" +version = "0.4.1" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +files = [ + {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"}, + {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + +[[package]] +name = "urllib3" +version = "2.5.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +files = [ + {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, + {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "virtualenv" +version = "20.34.0" +description = "Virtual Python Environment builder" +optional = false +python-versions = ">=3.8" +files = [ + {file = "virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026"}, + {file = "virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a"}, +] + +[package.dependencies] +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" +typing-extensions = {version = ">=4.13.2", markers = "python_version < \"3.11\""} + +[package.extras] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] + +[[package]] +name = "werkzeug" +version = "3.1.3" +description = "The comprehensive WSGI web application library." +optional = false +python-versions = ">=3.9" +files = [ + {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, + {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, +] + +[package.dependencies] +MarkupSafe = ">=2.1.1" + +[package.extras] +watchdog = ["watchdog (>=2.3)"] + +[[package]] +name = "wrapt" +version = "1.17.3" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04"}, + {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2"}, + {file = "wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c"}, + {file = "wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775"}, + {file = "wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd"}, + {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05"}, + {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418"}, + {file = "wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390"}, + {file = "wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6"}, + {file = "wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"}, + {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"}, + {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"}, + {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"}, + {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"}, + {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"}, + {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77"}, + {file = "wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7"}, + {file = "wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277"}, + {file = "wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d"}, + {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa"}, + {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050"}, + {file = "wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8"}, + {file = "wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb"}, + {file = "wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235"}, + {file = "wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c"}, + {file = "wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b"}, + {file = "wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa"}, + {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7"}, + {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4"}, + {file = "wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10"}, + {file = "wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6"}, + {file = "wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067"}, + {file = "wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454"}, + {file = "wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e"}, + {file = "wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f"}, + {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056"}, + {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804"}, + {file = "wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977"}, + {file = "wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116"}, + {file = "wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a"}, + {file = "wrapt-1.17.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f"}, + {file = "wrapt-1.17.3-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00"}, + {file = "wrapt-1.17.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56"}, + {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5"}, + {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22"}, + {file = "wrapt-1.17.3-cp38-cp38-win32.whl", hash = "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c"}, + {file = "wrapt-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9"}, + {file = "wrapt-1.17.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d"}, + {file = "wrapt-1.17.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a"}, + {file = "wrapt-1.17.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139"}, + {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df"}, + {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b"}, + {file = "wrapt-1.17.3-cp39-cp39-win32.whl", hash = "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81"}, + {file = "wrapt-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f"}, + {file = "wrapt-1.17.3-cp39-cp39-win_arm64.whl", hash = "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f"}, + {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"}, + {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"}, +] + +[[package]] +name = "zipp" +version = "3.23.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, + {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + +[[package]] +name = "zstandard" +version = "0.23.0" +description = "Zstandard bindings for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, + {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c"}, + {file = "zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813"}, + {file = "zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473"}, + {file = "zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160"}, + {file = "zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35"}, + {file = "zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d"}, + {file = "zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33"}, + {file = "zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd"}, + {file = "zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e"}, + {file = "zstandard-0.23.0-cp38-cp38-win32.whl", hash = "sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9"}, + {file = "zstandard-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5"}, + {file = "zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274"}, + {file = "zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58"}, + {file = "zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09"}, +] + +[package.dependencies] +cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\""} + +[package.extras] +cffi = ["cffi (>=1.11)"] + +[extras] +langchain = ["langchain"] +openai = ["openai"] + +[metadata] +lock-version = "2.0" +python-versions = ">=3.9,<4.0" +content-hash = "d0356916b5c7adba0ed8ea357edb8adcde09269bd83613df67976cd93a246aa3" diff --git a/pyproject.toml b/pyproject.toml index c49440761..891c5751d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,54 +1,48 @@ -[project] +[tool.poetry] name = "langfuse" + version = "3.2.6" description = "A client library for accessing langfuse" -authors = [{ name = "langfuse", email = "developers@langfuse.com" }] -requires-python = ">=3.9,<4.0" -readme = "README.md" +authors = ["langfuse "] license = "MIT" -dependencies = [ - "httpx>=0.15.4,<1.0", - "pydantic>=1.10.7, <3.0", - "backoff>=1.10.0", - "wrapt~=1.14", - "packaging>=23.2,<26.0", - "requests>=2,<3", - "opentelemetry-api>=1.33.1,<2", - "opentelemetry-sdk>=1.33.1,<2", - "opentelemetry-exporter-otlp-proto-http>=1.33.1,<2", -] +readme = "README.md" -[project.optional-dependencies] -openai = ["openai>=0.27.8"] -langchain = ["langchain>=0.0.309"] +[tool.poetry.dependencies] +python = ">=3.9,<4.0" +httpx = ">=0.15.4,<1.0" +pydantic = ">=1.10.7, <3.0" +backoff = ">=1.10.0" +openai = { version = ">=0.27.8", optional = true } +wrapt = "^1.14" +langchain = { version = ">=0.0.309", optional = true } +packaging = ">=23.2,<26.0" +requests = "^2" +opentelemetry-api = "^1.33.1" +opentelemetry-sdk = "^1.33.1" +opentelemetry-exporter-otlp-proto-http = "^1.33.1" -[project.scripts] -release = "scripts.release:main" +[tool.poetry.group.dev.dependencies] +pytest = ">=7.4,<9.0" +pytest-timeout = "^2.1.0" +pytest-xdist = "^3.3.1" +pre-commit = "^3.2.2" +pytest-asyncio = ">=0.21.1,<0.24.0" +pytest-httpserver = "^1.0.8" +ruff = ">=0.1.8,<0.6.0" +mypy = "^1.0.0" +langchain-openai = ">=0.0.5,<0.3" +langgraph = "^0.2.62" -[dependency-groups] -dev = [ - "pytest>=7.4,<9.0", - "pytest-timeout>=2.1.0,<3", - "pytest-xdist>=3.3.1,<4", - "pre-commit>=3.2.2,<4", - "pytest-asyncio>=0.21.1,<0.24.0", - "pytest-httpserver>=1.0.8,<2", - "ruff>=0.1.8,<0.6.0", - "mypy>=1.0.0,<2", - "langchain-openai>=0.0.5,<0.3", - "langgraph>=0.2.62,<0.3", -] -docs = ["pdoc>=14.4.0,<15"] +[tool.poetry.group.docs.dependencies] +pdoc = "^14.4.0" -[tool.uv] -default-groups = [ - "dev", - "docs", -] +[tool.poetry.extras] +openai = ["openai"] +langchain = ["langchain"] [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" [tool.pytest.ini_options] log_cli = true @@ -110,3 +104,6 @@ module = [ "langfuse.api.client" ] ignore_errors = true + +[tool.poetry.scripts] +release = "scripts.release:main" From 31c524c68c8aee4e126e4f29eb88c99c72ff623b Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:38:14 +0200 Subject: [PATCH 24/66] restore 2 --- CLAUDE.md | 204 +++++++++++++++++++----------------------------------- 1 file changed, 72 insertions(+), 132 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7514e08bb..b0f36e8d6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,175 +4,115 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -This is the **Langfuse Python SDK**, an observability and analytics platform for AI applications. It provides tracing, evaluation, and analytics for LLM applications through multiple interfaces: decorators, low-level SDK, and integrations with popular AI libraries. +This is the Langfuse Python SDK, a client library for accessing the Langfuse observability platform. The SDK provides integration with OpenTelemetry (OTel) for tracing, automatic instrumentation for popular LLM frameworks (OpenAI, Langchain, etc.), and direct API access to Langfuse's features. ## Development Commands -### Environment Setup +### Setup ```bash -# Using UV (preferred) -uv venv --python 3.12 -source .venv/bin/activate -uv sync +# Install Poetry plugins (one-time setup) +poetry self add poetry-dotenv-plugin +poetry self add poetry-bumpversion -# Using Poetry (legacy) +# Install all dependencies including optional extras poetry install --all-extras + +# Setup pre-commit hooks poetry run pre-commit install ``` ### Testing ```bash -# Run all tests +# Run all tests with verbose output poetry run pytest -s -v --log-cli-level=INFO -# Run specific test +# Run a specific test poetry run pytest -s -v --log-cli-level=INFO tests/test_core_sdk.py::test_flush -# Run with UV -uv run pytest -s -v --log-cli-level=INFO +# Run tests in parallel (faster) +poetry run pytest -s -v --log-cli-level=INFO -n auto ``` -### Memory for Running Unit Tests -- To run unit tests you must always use the env file, use: `UV_ENV_FILE=.env uv run pytest -s -v --log-cli-level=INFO tests/TESTFILE::TEST_NAME` - ### Code Quality ```bash -# Format code -ruff format . +# Format code with Ruff +poetry run ruff format . + +# Run linting (development config) +poetry run ruff check . -# Run linter (development config) -ruff check . +# Run type checking +poetry run mypy . -# Run linter (CI config) -ruff check --config ci.ruff.toml . +# Run pre-commit hooks manually +poetry run pre-commit run --all-files ``` -### Documentation +### Building and Releasing ```bash -# Generate SDK reference docs -poetry run pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse +# Build the package +poetry build -# Serve docs locally -poetry run pdoc --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse +# Run release script (handles versioning, building, tagging, and publishing) +poetry run release + +# Generate documentation +poetry run pdoc -o docs/ --docformat google --logo "https://langfuse.com/langfuse_logo.svg" langfuse ``` -## Architecture Overview +## Architecture ### Core Components -**Main SDK Client** (`langfuse/_client/client.py`) -- Built on OpenTelemetry foundations -- Provides span management for tracing (LangfuseSpan, LangfuseGeneration, LangfuseEvent) -- Thread-safe singleton pattern with multi-project support -- Handles both sync and async operations - -**Resource Manager** (`langfuse/_client/resource_manager.py`) -- Central coordination hub implementing thread-safe singleton -- Manages OpenTelemetry setup, API clients, background workers -- Handles media upload and score ingestion queues -- Provides graceful shutdown and resource cleanup - -**API Layer** (`langfuse/api/`) -- Auto-generated from OpenAPI spec using Fern -- Provides complete typed client for Langfuse API -- Organized by resources (prompts, datasets, observations, etc.) - -### SDK Interfaces - -**Three primary interaction patterns:** - -1. **Decorator Pattern** (`@observe`) - ```python - @observe(as_type="generation") - def my_llm_function(): - # Automatically traced - ``` - -2. **Low-level Client API** - ```python - langfuse = Langfuse() - span = langfuse.start_span(name="operation") - ``` - -3. **Integration Libraries** - ```python - from langfuse.openai import openai # Drop-in replacement - ``` - -### Integration Architecture - -**OpenAI Integration** (`langfuse/openai.py`) -- Drop-in replacement supporting both v0.x and v1.x -- Wraps all completion methods (chat, completions, streaming, async) -- Automatic metrics collection (tokens, cost, latency) - -**LangChain Integration** (`langfuse/langchain/`) -- CallbackHandler pattern for chain tracing -- Automatic span creation for chains, tools, and agents -- UUID mapping between LangChain runs and Langfuse spans - -### Background Processing - -**Task Manager** (`langfuse/_task_manager/`) -- Media upload processing with configurable workers -- Score ingestion with batching and retry logic -- Queue-based architecture with backpressure handling - -## Key Development Patterns - -### Multi-Project Safety -- Thread-safe singleton per public key prevents data leakage -- Project-scoped span processor filters ensure data isolation -- Disabled clients returned when project context is ambiguous - -### OpenTelemetry Foundation -- All tracing built on OTel primitives for standards compliance -- Custom span processor for Langfuse-specific export -- Proper context propagation across async boundaries - -### Testing Approach -- Comprehensive unit and integration tests -- API mocking through test wrappers -- Concurrency testing with ThreadPoolExecutor -- Proper resource cleanup in test teardown - -## File Structure Notes - -- `langfuse/_client/` - Core client implementation and tracing logic -- `langfuse/api/` - Auto-generated API client (excluded from linting) -- `langfuse/_utils/` - Utility functions for serialization, error handling, etc. -- `langfuse/_task_manager/` - Background processing workers -- `tests/` - Comprehensive test suite with integration tests -- `static/` - Test assets and sample files +- **`langfuse/_client/`**: Main SDK implementation built on OpenTelemetry + - `client.py`: Core Langfuse client with OTel integration + - `span.py`: LangfuseSpan, LangfuseGeneration, LangfuseEvent classes + - `observe.py`: Decorator for automatic instrumentation + - `datasets.py`: Dataset management functionality + +- **`langfuse/api/`**: Auto-generated Fern API client + - Contains all API resources and types + - Generated from OpenAPI spec - do not manually edit these files + +- **`langfuse/_task_manager/`**: Background processing + - Media upload handling and queue management + - Score ingestion consumer + +- **Integration modules**: + - `langfuse/openai.py`: OpenAI instrumentation + - `langfuse/langchain/`: Langchain integration via CallbackHandler + +### Key Design Patterns + +The SDK is built on OpenTelemetry for observability, using: +- Spans for tracing LLM operations +- Attributes for metadata (see `LangfuseOtelSpanAttributes`) +- Resource management for efficient batching and flushing + +The client follows an async-first design with automatic batching of events and background flushing to the Langfuse API. ## Configuration -### Environment Variables -Key environment variables for development: -- `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY` - API credentials -- `LANGFUSE_HOST` - Langfuse instance URL -- `LANGFUSE_DEBUG` - Enable debug logging -- `LANGFUSE_TRACING_ENABLED` - Enable/disable tracing +Environment variables (defined in `_client/environment_variables.py`): +- `LANGFUSE_PUBLIC_KEY` / `LANGFUSE_SECRET_KEY`: API credentials +- `LANGFUSE_HOST`: API endpoint (defaults to https://cloud.langfuse.com) +- `LANGFUSE_DEBUG`: Enable debug logging +- `LANGFUSE_TRACING_ENABLED`: Enable/disable tracing +- `LANGFUSE_SAMPLE_RATE`: Sampling rate for traces -### Test Configuration -- Tests require `.env` file based on `.env.template` -- Some E2E tests are skipped by default (remove decorators to run) -- CI uses different ruff config (`ci.ruff.toml`) +## Testing Notes -## Release Process +- Create `.env` file based on `.env.template` for integration tests +- E2E tests with external APIs (OpenAI, SERP) are typically skipped in CI +- Remove `@pytest.mark.skip` decorators in test files to run external API tests +- Tests use `respx` for HTTP mocking and `pytest-httpserver` for test servers -```bash -# Automated release -poetry run release +## Important Files -# Manual release steps -poetry version patch -poetry build -git commit -am "chore: release v{version}" -git tag v{version} -git push --tags -poetry publish -``` +- `pyproject.toml`: Poetry configuration, dependencies, and tool settings +- `ruff.toml`: Local development linting config (stricter) +- `ci.ruff.toml`: CI linting config (more permissive) +- `langfuse/version.py`: Version string (updated by release script) ## API Generation From 0d403e9c74790378a41f5e37f09e681725a553b3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:38:44 +0200 Subject: [PATCH 25/66] restore --- langfuse/langchain/CallbackHandler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/langfuse/langchain/CallbackHandler.py b/langfuse/langchain/CallbackHandler.py index d6cb6a7bf..03e73c3f2 100644 --- a/langfuse/langchain/CallbackHandler.py +++ b/langfuse/langchain/CallbackHandler.py @@ -458,7 +458,6 @@ def on_tool_start( input=input_str, metadata=meta, level="DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None, - as_type="tool", ) except Exception as e: From df71a699ff47d2e7dfbee5e0f67083a55ba4ba75 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:41:24 +0200 Subject: [PATCH 26/66] restore 3 --- .vscode/settings.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 41ac6ac98..60c1c477b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,9 +14,7 @@ "prettier.documentSelectors": [ "**/*.{cjs,mjs,ts,tsx,astro,md,mdx,json,yaml,yml}" ], - "python.testing.pytestArgs": [ - "tests" - ], + "python.testing.pytestArgs": ["tests"], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true } From c07a95a3f75691034c6fc85444481f945a0bbfe3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:44:46 +0200 Subject: [PATCH 27/66] simplify --- langfuse/_client/constants.py | 15 --------------- langfuse/_client/observe.py | 7 ++++--- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 2e32bbb58..99a5c6668 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -27,21 +27,6 @@ class ObservationType(str, enum.Enum): EVALUATOR = "EVALUATOR" GUARDRAIL = "GUARDRAIL" - -# Valid observation types for the @observe decorator (lowercase user interface) -VALID_OBSERVATION_TYPES = { - "span", - "event", - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - "guardrail", -} - ObservationTypeLiteralNoEvent: TypeAlias = Literal[ "span", "generation", diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index bed9a378b..48d6fa2bc 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -16,6 +16,7 @@ Union, cast, overload, + get_args, ) from opentelemetry.util._decorator import _AgnosticContextManager @@ -26,7 +27,6 @@ ) from langfuse._client.constants import ( - VALID_OBSERVATION_TYPES, ObservationTypeLiteralNoEvent, ) from langfuse._client.get_client import _set_current_public_key, get_client @@ -169,9 +169,10 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ - if as_type is not None and as_type not in VALID_OBSERVATION_TYPES: + valid_types = set(get_args(ObservationTypeLiteralNoEvent)) + if as_type is not None and as_type not in valid_types: self._log.warning( - f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(VALID_OBSERVATION_TYPES))}. Defaulting to 'span'." + f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(valid_types))}. Defaulting to 'span'." ) as_type = "span" From abddc4563fe977b94bf52723d8f6808259eb6e0e Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 14:44:55 +0200 Subject: [PATCH 28/66] simplift --- langfuse/_client/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 99a5c6668..f3fb6a2b3 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -27,6 +27,7 @@ class ObservationType(str, enum.Enum): EVALUATOR = "EVALUATOR" GUARDRAIL = "GUARDRAIL" + ObservationTypeLiteralNoEvent: TypeAlias = Literal[ "span", "generation", From 0b258363634d4885aa100c9e5c8b521833729386 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 15:04:39 +0200 Subject: [PATCH 29/66] simplify --- langfuse/_client/client.py | 71 ++++++++++++-------------------------- 1 file changed, 23 insertions(+), 48 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 538bfc87f..7d5fd9359 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -791,6 +791,7 @@ def start_as_current_observation( status_message: Optional status message for the observation end_on_exit (default: True): Whether to end the span automatically when leaving the context manager. If False, the span must be manually ended to avoid memory leaks. + # TODO: also add the generation like types here! The following parameters are only available when as_type="generation": completion_start_time: When the model started generating the response model: Name/identifier of the AI model used (e.g., "gpt-4") @@ -804,11 +805,16 @@ def start_as_current_observation( Example: ```python - # Create an agent observation - with langfuse.start_as_current_observation(name="planning-agent", as_type="agent") as agent: - # Do agent work - plan = create_plan() - agent.update(output=plan) + # Create a span + with langfuse.start_as_current_observation(name="process-query", as_type="span") as span: + # Do work + result = process_data() + span.update(output=result) + + # Create a child span automatically + with span.start_as_current_span(name="sub-operation") as child_span: + # Do sub-operation work + child_span.update(output="sub-result") # Create a tool observation with langfuse.start_as_current_observation(name="web-search", as_type="tool") as tool: @@ -827,47 +833,21 @@ def start_as_current_observation( generation.update(output=response) ``` """ - # Delegate to existing methods for consistency if as_type == "span": - return cast( - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], - ], - self.start_as_current_span( - trace_context=trace_context, - name=name, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - end_on_exit=end_on_exit, - ), + return self.start_as_current_span( + trace_context=trace_context, + name=name, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + end_on_exit=end_on_exit, ) if as_type == "generation": - return cast( - Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], - ], - self.start_as_current_generation( + return self.start_as_current_generation( trace_context=trace_context, name=name, input=input, @@ -883,8 +863,7 @@ def start_as_current_observation( cost_details=cost_details, prompt=prompt, end_on_exit=end_on_exit, - ), - ) + ) if trace_context: trace_id = trace_context.get("trace_id", None) @@ -897,8 +876,6 @@ def start_as_current_observation( return cast( Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], _AgnosticContextManager[LangfuseAgent], _AgnosticContextManager[LangfuseTool], _AgnosticContextManager[LangfuseChain], @@ -930,8 +907,6 @@ def start_as_current_observation( return cast( Union[ - _AgnosticContextManager[LangfuseGeneration], - _AgnosticContextManager[LangfuseSpan], _AgnosticContextManager[LangfuseAgent], _AgnosticContextManager[LangfuseTool], _AgnosticContextManager[LangfuseChain], From a09044ab21974b6ed953efe0ebc313ab5f0b4e17 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 15:08:48 +0200 Subject: [PATCH 30/66] fix case --- langfuse/_client/span.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 0d05f0567..8a5601042 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1319,7 +1319,7 @@ class LangfuseAgent(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseAgent span.""" - kwargs["observation_type"] = "AGENT" + kwargs["observation_type"] = "agent" super().__init__(**kwargs) @@ -1328,7 +1328,7 @@ class LangfuseTool(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseTool span.""" - kwargs["observation_type"] = "TOOL" + kwargs["observation_type"] = "tool" super().__init__(**kwargs) @@ -1337,7 +1337,7 @@ class LangfuseChain(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseChain span.""" - kwargs["observation_type"] = "CHAIN" + kwargs["observation_type"] = "chain" super().__init__(**kwargs) @@ -1346,7 +1346,7 @@ class LangfuseRetriever(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseRetriever span.""" - kwargs["observation_type"] = "RETRIEVER" + kwargs["observation_type"] = "retriever" super().__init__(**kwargs) @@ -1355,7 +1355,7 @@ class LangfuseEmbedding(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEmbedding span.""" - kwargs["observation_type"] = "EMBEDDING" + kwargs["observation_type"] = "embedding" super().__init__(**kwargs) @@ -1364,7 +1364,7 @@ class LangfuseEvaluator(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEvaluator span.""" - kwargs["observation_type"] = "EVALUATOR" + kwargs["observation_type"] = "evaluator" super().__init__(**kwargs) @@ -1373,5 +1373,5 @@ class LangfuseGuardrail(LangfuseGraphObservation): def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseGuardrail span.""" - kwargs["observation_type"] = "GUARDRAIL" + kwargs["observation_type"] = "guardrail" super().__init__(**kwargs) From e4bcc7bdbfb28cc68679304a4ecf048b26a9d587 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 15 Aug 2025 15:39:59 +0200 Subject: [PATCH 31/66] rearrange spans --- langfuse/_client/attributes.py | 17 +- langfuse/_client/client.py | 32 +- langfuse/_client/span.py | 524 +++++++++++++++++---------------- tests/test_otel.py | 49 +++ 4 files changed, 349 insertions(+), 273 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index 8705a0944..7a0247025 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -93,10 +93,10 @@ def create_span_attributes( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, version: Optional[str] = None, - observation_type: Optional[str] = None, + observation_type: Optional[Literal["span", "guardrail"]] = "span", ) -> dict: attributes = { - LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type or "span", + LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type, LangfuseOtelSpanAttributes.OBSERVATION_LEVEL: level, LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message, LangfuseOtelSpanAttributes.VERSION: version, @@ -123,9 +123,20 @@ def create_generation_attributes( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, + observation_type: Optional[ + Literal[ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ] + ] = "generation", ) -> dict: attributes = { - LangfuseOtelSpanAttributes.OBSERVATION_TYPE: "generation", + LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type, LangfuseOtelSpanAttributes.OBSERVATION_LEVEL: level, LangfuseOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message, LangfuseOtelSpanAttributes.VERSION: version, diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 7d5fd9359..bbb580fd5 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -848,22 +848,22 @@ def start_as_current_observation( if as_type == "generation": return self.start_as_current_generation( - trace_context=trace_context, - name=name, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - end_on_exit=end_on_exit, - ) + trace_context=trace_context, + name=name, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + end_on_exit=end_on_exit, + ) if trace_context: trace_id = trace_context.get("trace_id", None) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 8a5601042..5ebf32498 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -129,7 +129,15 @@ def __init__( attributes = {} - if as_type == "generation": + if as_type in [ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ]: attributes = create_generation_attributes( input=media_processed_input, output=media_processed_output, @@ -143,9 +151,22 @@ def __init__( usage_details=usage_details, cost_details=cost_details, prompt=prompt, + observation_type=cast( + Literal[ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ], + as_type, + ), ) else: + # For span-like types: "span", "guardrail", "event" attributes = create_span_attributes( input=media_processed_input, output=media_processed_output, @@ -153,7 +174,10 @@ def __init__( version=version, level=level, status_message=status_message, - observation_type=as_type, + observation_type=cast( + Optional[Literal["span", "guardrail"]], + as_type if as_type in ["span", "guardrail"] else None, + ), ) attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) @@ -514,18 +538,25 @@ def _process_media_in_attribute( return data -class LangfuseSpan(LangfuseSpanWrapper): - """Standard span implementation for general operations in Langfuse. +class LangfuseGenerationLikeObservation(LangfuseSpanWrapper): + """Base class for generation-like observations. - This class represents a general-purpose span that can be used to trace - any operation in your application. It extends the base LangfuseSpanWrapper - with specific methods for creating child spans, generations, and updating - span-specific attributes. + This class provides a common foundation for observation types that support + generation-specific parameters like model, usage details, and cost tracking. """ def __init__( self, *, + observation_type: Literal[ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ], otel_span: otel_trace_api.Span, langfuse_client: "Langfuse", input: Optional[Any] = None, @@ -535,23 +566,36 @@ def __init__( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, ): - """Initialize a new LangfuseSpan. + """Initialize a new generation-like observation span. Args: + observation_type: The specific observation type (e.g., "generation", "tool", ...) otel_span: The OpenTelemetry span to wrap langfuse_client: Reference to the parent Langfuse client - input: Input data for the span (any JSON-serializable object) - output: Output data from the span (any JSON-serializable object) - metadata: Additional metadata to associate with the span + input: Input data for the observation + output: Output data from the observation + metadata: Additional metadata to associate with the observation environment: The tracing environment version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + completion_start_time: When the generation started + model: Model identifier used for the generation + model_parameters: Parameters passed to the model + usage_details: Token or other usage statistics + cost_details: Cost breakdown for the operation + prompt: Reference to the prompt used """ super().__init__( otel_span=otel_span, - as_type="span", + as_type=observation_type, langfuse_client=langfuse_client, input=input, output=output, @@ -560,8 +604,25 @@ def __init__( version=version, level=level, status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, ) + # Store the observation type for use in update method + self._observation_type: Literal[ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ] = observation_type + def update( self, *, @@ -572,33 +633,151 @@ def update( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, **kwargs: Any, - ) -> "LangfuseSpan": - """Update this span with new information. + ) -> "LangfuseGenerationLikeObservation": + """Update this generation-like observation with new information. - This method updates the span with new information that becomes available + This method updates the observation with new information that becomes available during execution, such as outputs, metadata, or status changes. Args: - name: Span name + name: Observation name input: Updated input data for the operation output: Output data from the operation - metadata: Additional metadata to associate with the span + metadata: Additional metadata to associate with the observation version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + completion_start_time: When the generation started + model: Model identifier used for the generation + model_parameters: Parameters passed to the model + usage_details: Token or other usage statistics + cost_details: Cost breakdown for the operation + prompt: Reference to the prompt used **kwargs: Additional keyword arguments (ignored) + """ + if not self._otel_span.is_recording(): + return self - Example: - ```python - span = langfuse.start_span(name="process-data") - try: - # Do work - result = process_data() - span.update(output=result, metadata={"processing_time": 350}) - finally: - span.end() - ``` + processed_input = self._process_media_and_apply_mask( + data=input, field="input", span=self._otel_span + ) + processed_output = self._process_media_and_apply_mask( + data=output, field="output", span=self._otel_span + ) + processed_metadata = self._process_media_and_apply_mask( + data=metadata, field="metadata", span=self._otel_span + ) + + if name: + self._otel_span.update_name(name) + + attributes = create_generation_attributes( + input=processed_input, + output=processed_output, + metadata=processed_metadata, + version=version, + level=level, + status_message=status_message, + observation_type=self._observation_type, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + + self._otel_span.set_attributes(attributes=attributes) + + return self + + +class LangfuseSpanLikeObservation(LangfuseSpanWrapper): + """Base class for span-like observations. + + This class provides a common foundation for observation types that only need + basic span parameters without generation-specific features. + """ + + def __init__( + self, + *, + observation_type: Optional[Literal["span", "guardrail"]] = "span", + otel_span: otel_trace_api.Span, + langfuse_client: "Langfuse", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + environment: Optional[str] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ): + """Initialize a new span-like observation span. + + Args: + observation_type: The specific observation type (e.g., "guardrail", ...) + otel_span: The OpenTelemetry span to wrap + langfuse_client: Reference to the parent Langfuse client + input: Input data for the observation + output: Output data from the observation + metadata: Additional metadata to associate with the observation + environment: The tracing environment + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + """ + super().__init__( + otel_span=otel_span, + as_type=observation_type or "span", + langfuse_client=langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=environment, + version=version, + level=level, + status_message=status_message, + ) + + # Store the observation type for use in update method + self._observation_type: Literal["span", "guardrail"] = ( + observation_type or "span" + ) + + def update( + self, + *, + name: Optional[str] = None, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + **kwargs: Any, + ) -> "LangfuseSpanLikeObservation": + """Update this span-like observation with new information. + + This method updates the observation with new information that becomes available + during execution, such as outputs, metadata, or status changes. + + Args: + name: Observation name + input: Updated input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + **kwargs: Additional keyword arguments (ignored) """ if not self._otel_span.is_recording(): return self @@ -623,12 +802,62 @@ def update( version=version, level=level, status_message=status_message, + observation_type=self._observation_type, ) self._otel_span.set_attributes(attributes=attributes) return self + +class LangfuseSpan(LangfuseSpanLikeObservation): + """Standard span implementation for general operations in Langfuse. + + This class represents a general-purpose span that can be used to trace + any operation in your application. It extends the base LangfuseSpanWrapper + with specific methods for creating child spans, generations, and updating + span-specific attributes. + """ + + def __init__( + self, + *, + otel_span: otel_trace_api.Span, + langfuse_client: "Langfuse", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + environment: Optional[str] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ): + """Initialize a new LangfuseSpan. + + Args: + otel_span: The OpenTelemetry span to wrap + langfuse_client: Reference to the parent Langfuse client + input: Input data for the span (any JSON-serializable object) + output: Output data from the span (any JSON-serializable object) + metadata: Additional metadata to associate with the span + environment: The tracing environment + version: Version identifier for the code or component + level: Importance level of the span (info, warning, error) + status_message: Optional status message for the span + """ + super().__init__( + observation_type="span", + otel_span=otel_span, + langfuse_client=langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=environment, + version=version, + level=level, + status_message=status_message, + ) + def start_span( self, name: str, @@ -992,7 +1221,7 @@ def create_event( ) -class LangfuseGeneration(LangfuseSpanWrapper): +class LangfuseGeneration(LangfuseGenerationLikeObservation): """Specialized span implementation for AI model generations in Langfuse. This class represents a generation span specifically designed for tracking @@ -1039,8 +1268,8 @@ def __init__( prompt: Associated prompt template from Langfuse prompt management """ super().__init__( + observation_type="generation", otel_span=otel_span, - as_type="generation", langfuse_client=langfuse_client, input=input, output=output, @@ -1057,108 +1286,6 @@ def __init__( prompt=prompt, ) - def update( - self, - *, - name: Optional[str] = None, - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - **kwargs: Dict[str, Any], - ) -> "LangfuseGeneration": - """Update this generation span with new information. - - This method updates the generation span with new information that becomes - available during or after the model generation, such as model outputs, - token usage statistics, or cost details. - - Args: - name: The generation name - input: Updated input data for the model - output: Output from the model (e.g., completions) - metadata: Additional metadata to associate with the generation - version: Version identifier for the model or component - level: Importance level of the generation (info, warning, error) - status_message: Optional status message for the generation - completion_start_time: When the model started generating the response - model: Name/identifier of the AI model used (e.g., "gpt-4") - model_parameters: Parameters used for the model (e.g., temperature, max_tokens) - usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) - cost_details: Cost information for the model call - prompt: Associated prompt template from Langfuse prompt management - **kwargs: Additional keyword arguments (ignored) - - Example: - ```python - generation = langfuse.start_generation( - name="answer-generation", - model="gpt-4", - input={"prompt": "Explain quantum computing"} - ) - try: - # Call model API - response = llm.generate(...) - - # Update with results - generation.update( - output=response.text, - usage_details={ - "prompt_tokens": response.usage.prompt_tokens, - "completion_tokens": response.usage.completion_tokens, - "total_tokens": response.usage.total_tokens - }, - cost_details={ - "total_cost": 0.0035 - } - ) - finally: - generation.end() - ``` - """ - if not self._otel_span.is_recording(): - return self - - processed_input = self._process_media_and_apply_mask( - data=input, field="input", span=self._otel_span - ) - processed_output = self._process_media_and_apply_mask( - data=output, field="output", span=self._otel_span - ) - processed_metadata = self._process_media_and_apply_mask( - data=metadata, field="metadata", span=self._otel_span - ) - - if name: - self._otel_span.update_name(name) - - attributes = create_generation_attributes( - input=processed_input, - output=processed_output, - metadata=processed_metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ) - - self._otel_span.set_attributes(attributes=attributes) - - return self - class LangfuseEvent(LangfuseSpanWrapper): """Specialized span implementation for Langfuse Events.""" @@ -1203,118 +1330,7 @@ def __init__( ) -class LangfuseGraphObservation(LangfuseSpanWrapper): - """Base class for agentic workflow observations. - - This class provides a common foundation for specialized observation types - used in agentic workflows: agent, tool, chain, retriever, and embedding. - All graph observations use span-type attributes but with specific observation types. - """ - - def __init__( - self, - *, - observation_type: str, - otel_span: otel_trace_api.Span, - langfuse_client: "Langfuse", - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - environment: Optional[str] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - ): - """Initialize a new graph observation span. - - Args: - observation_type: The specific observation type (e.g., "agent", "tool", ...) - otel_span: The OpenTelemetry span to wrap - langfuse_client: Reference to the parent Langfuse client - input: Input data for the observation - output: Output data from the observation - metadata: Additional metadata to associate with the observation - environment: The tracing environment - version: Version identifier for the code or component - level: Importance level of the observation (info, warning, error) - status_message: Optional status message for the observation - """ - super().__init__( - otel_span=otel_span, - # TODO: decided attributes - as_type="span", # Use span-type attributes for all graph observations - langfuse_client=langfuse_client, - input=input, - output=output, - metadata=metadata, - environment=environment, - version=version, - level=level, - status_message=status_message, - ) - - # Store the observation type for use in update method - self._observation_type = observation_type - - def update( - self, - *, - name: Optional[str] = None, - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - **kwargs: Any, - ) -> "LangfuseGraphObservation": - """Update this graph observation with new information. - - This method updates the observation with new information that becomes available - during execution, such as outputs, metadata, or status changes. - - Args: - name: Observation name - input: Updated input data for the operation - output: Output data from the operation - metadata: Additional metadata to associate with the observation - version: Version identifier for the code or component - level: Importance level of the observation (info, warning, error) - status_message: Optional status message for the observation - **kwargs: Additional keyword arguments (ignored) - """ - if not self._otel_span.is_recording(): - return self - - processed_input = self._process_media_and_apply_mask( - data=input, field="input", span=self._otel_span - ) - processed_output = self._process_media_and_apply_mask( - data=output, field="output", span=self._otel_span - ) - processed_metadata = self._process_media_and_apply_mask( - data=metadata, field="metadata", span=self._otel_span - ) - - if name: - self._otel_span.update_name(name) - - attributes = create_span_attributes( - input=processed_input, - output=processed_output, - metadata=processed_metadata, - version=version, - level=level, - status_message=status_message, - observation_type=self._observation_type, - ) - - self._otel_span.set_attributes(attributes=attributes) - - return self - - -class LangfuseAgent(LangfuseGraphObservation): +class LangfuseAgent(LangfuseGenerationLikeObservation): """Specialized span for agent observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1323,7 +1339,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseTool(LangfuseGraphObservation): +class LangfuseTool(LangfuseGenerationLikeObservation): """Specialized span for tool observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1332,7 +1348,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseChain(LangfuseGraphObservation): +class LangfuseChain(LangfuseGenerationLikeObservation): """Specialized span for chain observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1341,7 +1357,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseRetriever(LangfuseGraphObservation): +class LangfuseRetriever(LangfuseGenerationLikeObservation): """Specialized span for retriever observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1350,7 +1366,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseEmbedding(LangfuseGraphObservation): +class LangfuseEmbedding(LangfuseGenerationLikeObservation): """Specialized span for embedding observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1359,7 +1375,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseEvaluator(LangfuseGraphObservation): +class LangfuseEvaluator(LangfuseGenerationLikeObservation): """Specialized span for evaluator observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1368,7 +1384,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseGuardrail(LangfuseGraphObservation): +class LangfuseGuardrail(LangfuseSpanLikeObservation): """Specialized span for guardrail observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: diff --git a/tests/test_otel.py b/tests/test_otel.py index dfa298161..b5614628a 100644 --- a/tests/test_otel.py +++ b/tests/test_otel.py @@ -589,6 +589,55 @@ def test_update_current_generation_name(self, langfuse_client, memory_exporter): ) assert len(original_spans) == 0, "Expected no generations with original name" + def test_start_as_current_observation_types(self, langfuse_client, memory_exporter): + """Test creating different observation types using start_as_current_observation.""" + # Test each observation type from ObservationTypeLiteralNoEvent + observation_types = [ + "span", + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + "guardrail", + ] + + for obs_type in observation_types: + with langfuse_client.start_as_current_observation( + name=f"test-{obs_type}", as_type=obs_type + ) as obs: + obs.update_trace(name=f"trace-{obs_type}") + + spans = [ + self.get_span_data(span) for span in memory_exporter.get_finished_spans() + ] + + # Find spans by name and verify their observation types + for obs_type in observation_types: + expected_name = f"test-{obs_type}" + matching_spans = [span for span in spans if span["name"] == expected_name] + assert ( + len(matching_spans) == 1 + ), f"Expected one span with name {expected_name}" + + span_data = matching_spans[0] + expected_otel_type = obs_type # OTEL attributes use lowercase + actual_type = span_data["attributes"].get( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE + ) + + # Debug: print all attributes for this span + print( + f"Span {expected_name} attributes: {list(span_data['attributes'].keys())}" + ) + print(f"Expected: {expected_otel_type}, Actual: {actual_type}") + + assert ( + actual_type == expected_otel_type + ), f"Expected observation type {expected_otel_type}, got {actual_type}" + def test_custom_trace_id(self, langfuse_client, memory_exporter): """Test setting a custom trace ID.""" # Create a custom trace ID From f0a322471bb2d9d2dc071ae6d0bbbf96f81fcc59 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:04:47 +0200 Subject: [PATCH 32/66] restrucure a bit --- langfuse/_client/constants.py | 63 ++- langfuse/_client/span.py | 865 +++++++++++++++++++++++----------- tests/test_otel.py | 135 ++++++ 3 files changed, 756 insertions(+), 307 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index f3fb6a2b3..3c442162a 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -3,33 +3,13 @@ This module defines constants used throughout the Langfuse OpenTelemetry integration. """ -import enum -from typing import Literal +from typing import Literal, List, get_args from typing_extensions import TypeAlias LANGFUSE_TRACER_NAME = "langfuse-sdk" -class ObservationType(str, enum.Enum): - """Enumeration of valid observation types for Langfuse tracing. - - This enum defines all the observation types that can be used with the @observe - decorator and other Langfuse SDK methods. - """ - - SPAN = "SPAN" - GENERATION = "GENERATION" - AGENT = "AGENT" - TOOL = "TOOL" - CHAIN = "CHAIN" - RETRIEVER = "RETRIEVER" - EMBEDDING = "EMBEDDING" - EVALUATOR = "EVALUATOR" - GUARDRAIL = "GUARDRAIL" - - -ObservationTypeLiteralNoEvent: TypeAlias = Literal[ - "span", +ObservationTypeGenerationLike: TypeAlias = Literal[ "generation", "agent", "tool", @@ -37,7 +17,44 @@ class ObservationType(str, enum.Enum): "retriever", "evaluator", "embedding", - "guardrail", ] +ObservationTypeLiteralNoEvent: TypeAlias = ( + ObservationTypeGenerationLike + | Literal[ + "span", + "guardrail", + ] +) + ObservationTypeLiteral: TypeAlias = ObservationTypeLiteralNoEvent | Literal["event"] +"""Enumeration of valid observation types for Langfuse tracing. + +This Literal defines all available observation types that can be used with the @observe +decorator and other Langfuse SDK methods. +""" + + +def get_observation_types_list( + literal_type: ObservationTypeGenerationLike + | ObservationTypeLiteralNoEvent + | ObservationTypeLiteral, +) -> List[str]: + """Flattens the Literal type to provide a list of strings. + + Args: + literal_type: A Literal type or union of Literals to flatten + + Returns: + Flat list of all string values contained in the Literal type + """ + result = [] + args = get_args(literal_type) + + for arg in args: + if hasattr(arg, "__args__"): + result.extend(get_observation_types_list(arg)) + else: + result.append(arg) + + return result diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 5ebf32498..59eb382e9 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -41,10 +41,23 @@ create_span_attributes, create_trace_attributes, ) -from langfuse._client.constants import ObservationTypeLiteral +from langfuse._client.constants import ( + ObservationTypeLiteral, + ObservationTypeGenerationLike, + ObservationTypeLiteralNoEvent, + get_observation_types_list, +) from langfuse.logger import langfuse_logger from langfuse.types import MapValue, ScoreDataType, SpanLevel +# Factory mapping for observation classes +# Note: "event" is handled separately due to special instantiation logic +# Populated after class definitions +_OBSERVATION_CLASS_MAP = {} + +# Cache generation-like types for performance +_GENERATION_LIKE_TYPES = None + class LangfuseSpanWrapper: """Abstract base class for all Langfuse span types. @@ -106,6 +119,8 @@ def __init__( ) self._langfuse_client = langfuse_client + self._observation_type = as_type + self.trace_id = self._langfuse_client._get_otel_trace_id(otel_span) self.id = self._langfuse_client._get_otel_span_id(otel_span) @@ -537,91 +552,8 @@ def _process_media_in_attribute( return data - -class LangfuseGenerationLikeObservation(LangfuseSpanWrapper): - """Base class for generation-like observations. - - This class provides a common foundation for observation types that support - generation-specific parameters like model, usage details, and cost tracking. - """ - - def __init__( - self, - *, - observation_type: Literal[ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ], - otel_span: otel_trace_api.Span, - langfuse_client: "Langfuse", - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - environment: Optional[str] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ): - """Initialize a new generation-like observation span. - - Args: - observation_type: The specific observation type (e.g., "generation", "tool", ...) - otel_span: The OpenTelemetry span to wrap - langfuse_client: Reference to the parent Langfuse client - input: Input data for the observation - output: Output data from the observation - metadata: Additional metadata to associate with the observation - environment: The tracing environment - version: Version identifier for the code or component - level: Importance level of the observation (info, warning, error) - status_message: Optional status message for the observation - completion_start_time: When the generation started - model: Model identifier used for the generation - model_parameters: Parameters passed to the model - usage_details: Token or other usage statistics - cost_details: Cost breakdown for the operation - prompt: Reference to the prompt used - """ - super().__init__( - otel_span=otel_span, - as_type=observation_type, - langfuse_client=langfuse_client, - input=input, - output=output, - metadata=metadata, - environment=environment, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ) - - # Store the observation type for use in update method - self._observation_type: Literal[ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ] = observation_type + # Add observation type tracking and unified update method + _observation_type: ObservationTypeLiteral def update( self, @@ -640,131 +572,8 @@ def update( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, **kwargs: Any, - ) -> "LangfuseGenerationLikeObservation": - """Update this generation-like observation with new information. - - This method updates the observation with new information that becomes available - during execution, such as outputs, metadata, or status changes. - - Args: - name: Observation name - input: Updated input data for the operation - output: Output data from the operation - metadata: Additional metadata to associate with the observation - version: Version identifier for the code or component - level: Importance level of the observation (info, warning, error) - status_message: Optional status message for the observation - completion_start_time: When the generation started - model: Model identifier used for the generation - model_parameters: Parameters passed to the model - usage_details: Token or other usage statistics - cost_details: Cost breakdown for the operation - prompt: Reference to the prompt used - **kwargs: Additional keyword arguments (ignored) - """ - if not self._otel_span.is_recording(): - return self - - processed_input = self._process_media_and_apply_mask( - data=input, field="input", span=self._otel_span - ) - processed_output = self._process_media_and_apply_mask( - data=output, field="output", span=self._otel_span - ) - processed_metadata = self._process_media_and_apply_mask( - data=metadata, field="metadata", span=self._otel_span - ) - - if name: - self._otel_span.update_name(name) - - attributes = create_generation_attributes( - input=processed_input, - output=processed_output, - metadata=processed_metadata, - version=version, - level=level, - status_message=status_message, - observation_type=self._observation_type, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ) - - self._otel_span.set_attributes(attributes=attributes) - - return self - - -class LangfuseSpanLikeObservation(LangfuseSpanWrapper): - """Base class for span-like observations. - - This class provides a common foundation for observation types that only need - basic span parameters without generation-specific features. - """ - - def __init__( - self, - *, - observation_type: Optional[Literal["span", "guardrail"]] = "span", - otel_span: otel_trace_api.Span, - langfuse_client: "Langfuse", - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - environment: Optional[str] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - ): - """Initialize a new span-like observation span. - - Args: - observation_type: The specific observation type (e.g., "guardrail", ...) - otel_span: The OpenTelemetry span to wrap - langfuse_client: Reference to the parent Langfuse client - input: Input data for the observation - output: Output data from the observation - metadata: Additional metadata to associate with the observation - environment: The tracing environment - version: Version identifier for the code or component - level: Importance level of the observation (info, warning, error) - status_message: Optional status message for the observation - """ - super().__init__( - otel_span=otel_span, - as_type=observation_type or "span", - langfuse_client=langfuse_client, - input=input, - output=output, - metadata=metadata, - environment=environment, - version=version, - level=level, - status_message=status_message, - ) - - # Store the observation type for use in update method - self._observation_type: Literal["span", "guardrail"] = ( - observation_type or "span" - ) - - def update( - self, - *, - name: Optional[str] = None, - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - **kwargs: Any, - ) -> "LangfuseSpanLikeObservation": - """Update this span-like observation with new information. + ) -> "LangfuseSpanWrapper": + """Update this observation with new information. This method updates the observation with new information that becomes available during execution, such as outputs, metadata, or status changes. @@ -777,6 +586,12 @@ def update( version: Version identifier for the code or component level: Importance level of the observation (info, warning, error) status_message: Optional status message for the observation + completion_start_time: When the generation started (for generation types) + model: Model identifier used (for generation types) + model_parameters: Parameters passed to the model (for generation types) + usage_details: Token or other usage statistics (for generation types) + cost_details: Cost breakdown for the operation (for generation types) + prompt: Reference to the prompt used (for generation types) **kwargs: Additional keyword arguments (ignored) """ if not self._otel_span.is_recording(): @@ -795,22 +610,65 @@ def update( if name: self._otel_span.update_name(name) - attributes = create_span_attributes( - input=processed_input, - output=processed_output, - metadata=processed_metadata, - version=version, - level=level, - status_message=status_message, - observation_type=self._observation_type, - ) + # Use same logic as __init__ to determine which attributes to create + if self._observation_type in [ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ]: + attributes = create_generation_attributes( + input=processed_input, + output=processed_output, + metadata=processed_metadata, + version=version, + level=level, + status_message=status_message, + observation_type=cast( + Literal[ + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + ], + self._observation_type, + ), + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + else: + # For span-like types: "span", "guardrail", "event" + attributes = create_span_attributes( + input=processed_input, + output=processed_output, + metadata=processed_metadata, + version=version, + level=level, + status_message=status_message, + observation_type=cast( + Optional[Literal["span", "guardrail"]], + self._observation_type + if self._observation_type in ["span", "guardrail"] + else None, + ), + ) self._otel_span.set_attributes(attributes=attributes) return self -class LangfuseSpan(LangfuseSpanLikeObservation): +class LangfuseSpan(LangfuseSpanWrapper): """Standard span implementation for general operations in Langfuse. This class represents a general-purpose span that can be used to trace @@ -846,7 +704,7 @@ def __init__( status_message: Optional status message for the span """ super().__init__( - observation_type="span", + as_type="span", otel_span=otel_span, langfuse_client=langfuse_client, input=input, @@ -906,19 +764,18 @@ def start_span( parent_span.end() ``` """ - with otel_trace_api.use_span(self._otel_span): - new_otel_span = self._langfuse_client._otel_tracer.start_span(name=name) - - return LangfuseSpan( - otel_span=new_otel_span, - langfuse_client=self._langfuse_client, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, + return cast( + "LangfuseSpan", + self.start_observation( + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ), ) def start_as_current_span( @@ -968,11 +825,9 @@ def start_as_current_span( """ return cast( _AgnosticContextManager["LangfuseSpan"], - self._langfuse_client._create_span_with_parent_context( + self.start_as_current_observation( name=name, as_type="span", - remote_parent_span=None, - parent=self._otel_span, input=input, output=output, metadata=metadata, @@ -1056,25 +911,24 @@ def start_generation( span.end() ``` """ - with otel_trace_api.use_span(self._otel_span): - new_otel_span = self._langfuse_client._otel_tracer.start_span(name=name) - - return LangfuseGeneration( - otel_span=new_otel_span, - langfuse_client=self._langfuse_client, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, + return cast( + "LangfuseGeneration", + self.start_observation( + name=name, + as_type="generation", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), ) def start_as_current_generation( @@ -1148,11 +1002,9 @@ def start_as_current_generation( """ return cast( _AgnosticContextManager["LangfuseGeneration"], - self._langfuse_client._create_span_with_parent_context( + self.start_as_current_observation( name=name, as_type="generation", - remote_parent_span=None, - parent=self._otel_span, input=input, output=output, metadata=metadata, @@ -1220,15 +1072,445 @@ def create_event( ).end(end_time=timestamp), ) - -class LangfuseGeneration(LangfuseGenerationLikeObservation): - """Specialized span implementation for AI model generations in Langfuse. - - This class represents a generation span specifically designed for tracking - AI/LLM operations. It extends the base LangfuseSpanWrapper with specialized - attributes for model details, token usage, and costs. - """ - + # Generic child creation methods with overloads for type safety + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["span"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> "LangfuseSpan": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["generation"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseGeneration": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["agent"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseAgent": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["tool"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseTool": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["chain"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseChain": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["retriever"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseRetriever": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["evaluator"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseEvaluator": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["embedding"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseEmbedding": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["guardrail"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> "LangfuseGuardrail": ... + + @overload + def start_observation( + self, + *, + name: str, + as_type: Literal["event"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> "LangfuseEvent": ... + + def start_observation( + self, + *, + name: str, + as_type: ObservationTypeLiteral, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> Union[ + "LangfuseSpan", + "LangfuseGeneration", + "LangfuseAgent", + "LangfuseTool", + "LangfuseChain", + "LangfuseRetriever", + "LangfuseEvaluator", + "LangfuseEmbedding", + "LangfuseGuardrail", + "LangfuseEvent", + ]: + """Create a new child observation of the specified type. + + This is the generic method for creating any type of child observation. + Unlike start_as_current_observation(), this method does not set the new + observation as the current observation in the context. + + Args: + name: Name of the observation + as_type: Type of observation to create + input: Input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + completion_start_time: When the model started generating (for generation types) + model: Name/identifier of the AI model used (for generation types) + model_parameters: Parameters used for the model (for generation types) + usage_details: Token usage information (for generation types) + cost_details: Cost information (for generation types) + prompt: Associated prompt template (for generation types) + + Returns: + A new observation of the specified type that must be ended with .end() + """ + if as_type == "event": + timestamp = time_ns() + event_span = self._langfuse_client._otel_tracer.start_span( + name=name, start_time=timestamp + ) + return cast( + LangfuseEvent, + LangfuseEvent( + otel_span=event_span, + langfuse_client=self._langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=self._environment, + version=version, + level=level, + status_message=status_message, + ).end(end_time=timestamp), + ) + + observation_class = _OBSERVATION_CLASS_MAP.get(as_type) + if not observation_class: + raise ValueError(f"Unknown observation type: {as_type}") + + with otel_trace_api.use_span(self._otel_span): + new_otel_span = self._langfuse_client._otel_tracer.start_span(name=name) + + common_args = { + "otel_span": new_otel_span, + "langfuse_client": self._langfuse_client, + "environment": self._environment, + "input": input, + "output": output, + "metadata": metadata, + "version": version, + "level": level, + "status_message": status_message, + } + + # TODO: perf, cache this value? "calculated" on every observation create + # if as_type in get_observation_types_list(ObservationTypeGenerationLike): + if as_type in ObservationTypeGenerationLike.__args__: + common_args.update( + { + "completion_start_time": completion_start_time, + "model": model, + "model_parameters": model_parameters, + "usage_details": usage_details, + "cost_details": cost_details, + "prompt": prompt, + } + ) + + return observation_class(**common_args) + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["span"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseSpan"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["generation"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> _AgnosticContextManager["LangfuseGeneration"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: ObservationTypeGenerationLike, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> _AgnosticContextManager[ + Union[ + "LangfuseAgent", + "LangfuseTool", + "LangfuseChain", + "LangfuseRetriever", + "LangfuseEvaluator", + "LangfuseEmbedding", + ] + ]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["guardrail"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseGuardrail"]: ... + + def start_as_current_observation( + self, + *, + name: str, + as_type: ObservationTypeLiteralNoEvent, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ): + """Create a new child observation and set it as the current observation in a context manager. + + This is the generic method for creating any type of child observation with + context management. It delegates to the client's _create_span_with_parent_context method. + + Args: + name: Name of the observation + as_type: Type of observation to create + input: Input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation (info, warning, error) + status_message: Optional status message for the observation + completion_start_time: When the model started generating (for generation types) + model: Name/identifier of the AI model used (for generation types) + model_parameters: Parameters used for the model (for generation types) + usage_details: Token usage information (for generation types) + cost_details: Cost information (for generation types) + prompt: Associated prompt template (for generation types) + + Returns: + A context manager that yields a new observation of the specified type + """ + return self._langfuse_client._create_span_with_parent_context( + name=name, + as_type=as_type, + remote_parent_span=None, + parent=self._otel_span, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + + +class LangfuseGeneration(LangfuseSpanWrapper): + """Specialized span implementation for AI model generations in Langfuse. + + This class represents a generation span specifically designed for tracking + AI/LLM operations. It extends the base LangfuseSpanWrapper with specialized + attributes for model details, token usage, and costs. + """ + def __init__( self, *, @@ -1268,7 +1550,7 @@ def __init__( prompt: Associated prompt template from Langfuse prompt management """ super().__init__( - observation_type="generation", + as_type="generation", otel_span=otel_span, langfuse_client=langfuse_client, input=input, @@ -1330,64 +1612,79 @@ def __init__( ) -class LangfuseAgent(LangfuseGenerationLikeObservation): +class LangfuseAgent(LangfuseSpanWrapper): """Specialized span for agent observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseAgent span.""" - kwargs["observation_type"] = "agent" + kwargs["as_type"] = "agent" super().__init__(**kwargs) -class LangfuseTool(LangfuseGenerationLikeObservation): +class LangfuseTool(LangfuseSpanWrapper): """Specialized span for tool observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseTool span.""" - kwargs["observation_type"] = "tool" + kwargs["as_type"] = "tool" super().__init__(**kwargs) -class LangfuseChain(LangfuseGenerationLikeObservation): +class LangfuseChain(LangfuseSpanWrapper): """Specialized span for chain observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseChain span.""" - kwargs["observation_type"] = "chain" + kwargs["as_type"] = "chain" super().__init__(**kwargs) -class LangfuseRetriever(LangfuseGenerationLikeObservation): +class LangfuseRetriever(LangfuseSpanWrapper): """Specialized span for retriever observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseRetriever span.""" - kwargs["observation_type"] = "retriever" + kwargs["as_type"] = "retriever" super().__init__(**kwargs) -class LangfuseEmbedding(LangfuseGenerationLikeObservation): +class LangfuseEmbedding(LangfuseSpanWrapper): """Specialized span for embedding observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEmbedding span.""" - kwargs["observation_type"] = "embedding" + kwargs["as_type"] = "embedding" super().__init__(**kwargs) -class LangfuseEvaluator(LangfuseGenerationLikeObservation): +class LangfuseEvaluator(LangfuseSpanWrapper): """Specialized span for evaluator observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEvaluator span.""" - kwargs["observation_type"] = "evaluator" + kwargs["as_type"] = "evaluator" super().__init__(**kwargs) -class LangfuseGuardrail(LangfuseSpanLikeObservation): +class LangfuseGuardrail(LangfuseSpanWrapper): """Specialized span for guardrail observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseGuardrail span.""" - kwargs["observation_type"] = "guardrail" + kwargs["as_type"] = "guardrail" super().__init__(**kwargs) + + +_OBSERVATION_CLASS_MAP.update( + { + "span": LangfuseSpan, + "generation": LangfuseGeneration, + "agent": LangfuseAgent, + "tool": LangfuseTool, + "chain": LangfuseChain, + "retriever": LangfuseRetriever, + "evaluator": LangfuseEvaluator, + "embedding": LangfuseEmbedding, + "guardrail": LangfuseGuardrail, + } +) diff --git a/tests/test_otel.py b/tests/test_otel.py index b5614628a..05ffbb026 100644 --- a/tests/test_otel.py +++ b/tests/test_otel.py @@ -638,6 +638,141 @@ def test_start_as_current_observation_types(self, langfuse_client, memory_export actual_type == expected_otel_type ), f"Expected observation type {expected_otel_type}, got {actual_type}" + def test_start_observation(self, langfuse_client, memory_exporter): + """Test creating different observation types using start_observation.""" + from langfuse._client.constants import ( + ObservationTypeGenerationLike, + ObservationTypeLiteral, + get_observation_types_list, + ) + + # Test each observation type defined in constants - this ensures we test all supported types + observation_types = get_observation_types_list(ObservationTypeLiteral) + + # Create a main span to use for child creation + with langfuse_client.start_as_current_span( + name="factory-test-parent" + ) as parent_span: + created_observations = [] + + for obs_type in observation_types: + if obs_type in get_observation_types_list( + ObservationTypeGenerationLike + ): + # Generation-like types with extra parameters + obs = parent_span.start_observation( + name=f"factory-{obs_type}", + as_type=obs_type, + input={"test": f"{obs_type}_input"}, + model="test-model", + model_parameters={"temperature": 0.7}, + usage_details={"input": 10, "output": 20}, + ) + if obs_type != "event": # Events are auto-ended + obs.end() + created_observations.append((obs_type, obs)) + elif obs_type == "event": + # Test event creation through start_observation (should be auto-ended) + obs = parent_span.start_observation( + name=f"factory-{obs_type}", + as_type=obs_type, + input={"test": f"{obs_type}_input"}, + ) + created_observations.append((obs_type, obs)) + else: + # Span-like types (span, guardrail) + obs = parent_span.start_observation( + name=f"factory-{obs_type}", + as_type=obs_type, + input={"test": f"{obs_type}_input"}, + ) + obs.end() + created_observations.append((obs_type, obs)) + + spans = [ + self.get_span_data(span) for span in memory_exporter.get_finished_spans() + ] + + # Verify factory pattern created correct observation types + for obs_type in observation_types: + expected_name = f"factory-{obs_type}" + matching_spans = [span for span in spans if span["name"] == expected_name] + assert ( + len(matching_spans) == 1 + ), f"Expected one span with name {expected_name}, found {len(matching_spans)}" + + span_data = matching_spans[0] + actual_type = span_data["attributes"].get( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE + ) + + assert ( + actual_type == obs_type + ), f"Factory pattern failed: Expected observation type {obs_type}, got {actual_type}" + + # Ensure returned objects are of correct types + for obs_type, obs_instance in created_observations: + if obs_type == "span": + from langfuse._client.span import LangfuseSpan + + assert isinstance( + obs_instance, LangfuseSpan + ), f"Expected LangfuseSpan, got {type(obs_instance)}" + elif obs_type == "generation": + from langfuse._client.span import LangfuseGeneration + + assert isinstance( + obs_instance, LangfuseGeneration + ), f"Expected LangfuseGeneration, got {type(obs_instance)}" + elif obs_type == "agent": + from langfuse._client.span import LangfuseAgent + + assert isinstance( + obs_instance, LangfuseAgent + ), f"Expected LangfuseAgent, got {type(obs_instance)}" + elif obs_type == "tool": + from langfuse._client.span import LangfuseTool + + assert isinstance( + obs_instance, LangfuseTool + ), f"Expected LangfuseTool, got {type(obs_instance)}" + elif obs_type == "chain": + from langfuse._client.span import LangfuseChain + + assert isinstance( + obs_instance, LangfuseChain + ), f"Expected LangfuseChain, got {type(obs_instance)}" + elif obs_type == "retriever": + from langfuse._client.span import LangfuseRetriever + + assert isinstance( + obs_instance, LangfuseRetriever + ), f"Expected LangfuseRetriever, got {type(obs_instance)}" + elif obs_type == "evaluator": + from langfuse._client.span import LangfuseEvaluator + + assert isinstance( + obs_instance, LangfuseEvaluator + ), f"Expected LangfuseEvaluator, got {type(obs_instance)}" + elif obs_type == "embedding": + from langfuse._client.span import LangfuseEmbedding + + assert isinstance( + obs_instance, LangfuseEmbedding + ), f"Expected LangfuseEmbedding, got {type(obs_instance)}" + elif obs_type == "guardrail": + from langfuse._client.span import LangfuseGuardrail + + assert isinstance( + obs_instance, LangfuseGuardrail + ), f"Expected LangfuseGuardrail, got {type(obs_instance)}" + elif obs_type == "event": + from langfuse._client.span import LangfuseEvent + + assert isinstance( + obs_instance, LangfuseEvent + ), f"Expected LangfuseEvent, got {type(obs_instance)}" + def test_custom_trace_id(self, langfuse_client, memory_exporter): """Test setting a custom trace ID.""" # Create a custom trace ID From 04d65767f406a20e6d7d2535450e9144e1badd69 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:10:08 +0200 Subject: [PATCH 33/66] cleanup --- langfuse/_client/attributes.py | 14 +++----------- langfuse/_client/constants.py | 1 + langfuse/_client/span.py | 21 ++------------------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index 7a0247025..284db2b50 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -14,6 +14,8 @@ from datetime import datetime from typing import Any, Dict, List, Literal, Optional, Union +from langfuse._client.constants import ObservationTypeGenerationLike + from langfuse._utils.serializer import EventSerializer from langfuse.model import PromptClient from langfuse.types import MapValue, SpanLevel @@ -123,17 +125,7 @@ def create_generation_attributes( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - observation_type: Optional[ - Literal[ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ] - ] = "generation", + observation_type: Optional[ObservationTypeGenerationLike] = "generation", ) -> dict: attributes = { LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type, diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 3c442162a..8d956cdec 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -9,6 +9,7 @@ LANGFUSE_TRACER_NAME = "langfuse-sdk" +"""Note: this type is used with .__args__ in some cases and therefore must remain flat""" ObservationTypeGenerationLike: TypeAlias = Literal[ "generation", "agent", diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 59eb382e9..c6b500128 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -45,7 +45,6 @@ ObservationTypeLiteral, ObservationTypeGenerationLike, ObservationTypeLiteralNoEvent, - get_observation_types_list, ) from langfuse.logger import langfuse_logger from langfuse.types import MapValue, ScoreDataType, SpanLevel @@ -144,15 +143,7 @@ def __init__( attributes = {} - if as_type in [ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ]: + if as_type in ObservationTypeGenerationLike.__args__: attributes = create_generation_attributes( input=media_processed_input, output=media_processed_output, @@ -611,15 +602,7 @@ def update( self._otel_span.update_name(name) # Use same logic as __init__ to determine which attributes to create - if self._observation_type in [ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ]: + if self._observation_type in ObservationTypeGenerationLike.__args__: attributes = create_generation_attributes( input=processed_input, output=processed_output, From 79cb0a5ede36d17093ab30c5a7d3888e2b837ee3 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:31:17 +0200 Subject: [PATCH 34/66] make mypy happy --- langfuse/_client/span.py | 129 +++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 74 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index c6b500128..acdbd474e 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -22,8 +22,10 @@ List, Literal, Optional, + Type, Union, cast, + get_args, overload, ) @@ -52,10 +54,7 @@ # Factory mapping for observation classes # Note: "event" is handled separately due to special instantiation logic # Populated after class definitions -_OBSERVATION_CLASS_MAP = {} - -# Cache generation-like types for performance -_GENERATION_LIKE_TYPES = None +_OBSERVATION_CLASS_MAP: Dict[str, Type["LangfuseSpanWrapper"]] = {} class LangfuseSpanWrapper: @@ -143,7 +142,7 @@ def __init__( attributes = {} - if as_type in ObservationTypeGenerationLike.__args__: + if as_type in get_args(ObservationTypeGenerationLike): attributes = create_generation_attributes( input=media_processed_input, output=media_processed_output, @@ -602,7 +601,7 @@ def update( self._otel_span.update_name(name) # Use same logic as __init__ to determine which attributes to create - if self._observation_type in ObservationTypeGenerationLike.__args__: + if self._observation_type in get_args(ObservationTypeGenerationLike): attributes = create_generation_attributes( input=processed_input, output=processed_output, @@ -747,18 +746,15 @@ def start_span( parent_span.end() ``` """ - return cast( - "LangfuseSpan", - self.start_observation( - name=name, - as_type="span", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ), + return self.start_observation( + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, ) def start_as_current_span( @@ -806,18 +802,15 @@ def start_as_current_span( parent_span.update(output=result) ``` """ - return cast( - _AgnosticContextManager["LangfuseSpan"], - self.start_as_current_observation( - name=name, - as_type="span", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ), + return self.start_as_current_observation( + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, ) def start_generation( @@ -894,24 +887,21 @@ def start_generation( span.end() ``` """ - return cast( - "LangfuseGeneration", - self.start_observation( - name=name, - as_type="generation", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), + return self.start_observation( + name=name, + as_type="generation", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, ) def start_as_current_generation( @@ -1331,9 +1321,7 @@ def start_observation( "status_message": status_message, } - # TODO: perf, cache this value? "calculated" on every observation create - # if as_type in get_observation_types_list(ObservationTypeGenerationLike): - if as_type in ObservationTypeGenerationLike.__args__: + if as_type in get_args(ObservationTypeGenerationLike): common_args.update( { "completion_start_time": completion_start_time, @@ -1345,7 +1333,7 @@ def start_observation( } ) - return observation_class(**common_args) + return observation_class(**common_args) # type: ignore[no-any-return,return-value,arg-type] @overload def start_as_current_observation( @@ -1361,26 +1349,6 @@ def start_as_current_observation( status_message: Optional[str] = None, ) -> _AgnosticContextManager["LangfuseSpan"]: ... - @overload - def start_as_current_observation( - self, - *, - name: str, - as_type: Literal["generation"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ) -> _AgnosticContextManager["LangfuseGeneration"]: ... - @overload def start_as_current_observation( self, @@ -1424,7 +1392,7 @@ def start_as_current_observation( status_message: Optional[str] = None, ) -> _AgnosticContextManager["LangfuseGuardrail"]: ... - def start_as_current_observation( + def start_as_current_observation( # type: ignore[misc] self, *, name: str, @@ -1441,7 +1409,20 @@ def start_as_current_observation( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - ): + # TODO: or union of context managers? + ) -> _AgnosticContextManager[ + Union[ + "LangfuseSpan", + "LangfuseGeneration", + "LangfuseAgent", + "LangfuseTool", + "LangfuseChain", + "LangfuseRetriever", + "LangfuseEvaluator", + "LangfuseEmbedding", + "LangfuseGuardrail", + ] + ]: """Create a new child observation and set it as the current observation in a context manager. This is the generic method for creating any type of child observation with From 8756e11e96c94478fe3c13e8ba2dc1a450f25084 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:37:25 +0200 Subject: [PATCH 35/66] py3.9 compat --- langfuse/_client/constants.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 8d956cdec..b9345c1b9 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -3,7 +3,7 @@ This module defines constants used throughout the Langfuse OpenTelemetry integration. """ -from typing import Literal, List, get_args +from typing import Literal, List, get_args, Union from typing_extensions import TypeAlias LANGFUSE_TRACER_NAME = "langfuse-sdk" @@ -20,15 +20,17 @@ "embedding", ] -ObservationTypeLiteralNoEvent: TypeAlias = ( - ObservationTypeGenerationLike - | Literal[ +ObservationTypeLiteralNoEvent: TypeAlias = Union[ + ObservationTypeGenerationLike, + Literal[ "span", "guardrail", - ] -) + ], +] -ObservationTypeLiteral: TypeAlias = ObservationTypeLiteralNoEvent | Literal["event"] +ObservationTypeLiteral: TypeAlias = Union[ + ObservationTypeLiteralNoEvent, Literal["event"] +] """Enumeration of valid observation types for Langfuse tracing. This Literal defines all available observation types that can be used with the @observe @@ -37,9 +39,11 @@ def get_observation_types_list( - literal_type: ObservationTypeGenerationLike - | ObservationTypeLiteralNoEvent - | ObservationTypeLiteral, + literal_type: Union[ + ObservationTypeGenerationLike, + ObservationTypeLiteralNoEvent, + ObservationTypeLiteral, + ], ) -> List[str]: """Flattens the Literal type to provide a list of strings. From 9f510ad10bb8ab0d5319cbc55c12dce22cd4c972 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:46:45 +0200 Subject: [PATCH 36/66] happy mypy --- langfuse/_client/constants.py | 10 +++------- langfuse/_client/observe.py | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index b9345c1b9..12d307ffa 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -3,7 +3,7 @@ This module defines constants used throughout the Langfuse OpenTelemetry integration. """ -from typing import Literal, List, get_args, Union +from typing import Literal, List, get_args, Union, Any from typing_extensions import TypeAlias LANGFUSE_TRACER_NAME = "langfuse-sdk" @@ -39,16 +39,12 @@ def get_observation_types_list( - literal_type: Union[ - ObservationTypeGenerationLike, - ObservationTypeLiteralNoEvent, - ObservationTypeLiteral, - ], + literal_type: Any, ) -> List[str]: """Flattens the Literal type to provide a list of strings. Args: - literal_type: A Literal type or union of Literals to flatten + literal_type: A Literal type, TypeAlias, or union of Literals to flatten Returns: Flat list of all string values contained in the Literal type diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 48d6fa2bc..abc7ddc91 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -16,7 +16,6 @@ Union, cast, overload, - get_args, ) from opentelemetry.util._decorator import _AgnosticContextManager @@ -28,6 +27,7 @@ from langfuse._client.constants import ( ObservationTypeLiteralNoEvent, + get_observation_types_list, ) from langfuse._client.get_client import _set_current_public_key, get_client from langfuse._client.span import ( @@ -169,7 +169,7 @@ def sub_process(): - For async functions, the decorator returns an async function wrapper. - For sync functions, the decorator returns a synchronous wrapper. """ - valid_types = set(get_args(ObservationTypeLiteralNoEvent)) + valid_types = set(get_observation_types_list(ObservationTypeLiteralNoEvent)) if as_type is not None and as_type not in valid_types: self._log.warning( f"Invalid as_type '{as_type}'. Valid types are: {', '.join(sorted(valid_types))}. Defaulting to 'span'." From 4498380524f6ba3415a63cbb2e37b9500fd7feb0 Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 14:56:10 +0200 Subject: [PATCH 37/66] cleanup --- tests/test_manual_graph_instrumentation.py | 201 --------------------- 1 file changed, 201 deletions(-) delete mode 100644 tests/test_manual_graph_instrumentation.py diff --git a/tests/test_manual_graph_instrumentation.py b/tests/test_manual_graph_instrumentation.py deleted file mode 100644 index 4e7364fad..000000000 --- a/tests/test_manual_graph_instrumentation.py +++ /dev/null @@ -1,201 +0,0 @@ -import time - -from langfuse import Langfuse, observe -from tests.utils import create_uuid, get_api - - -def test_observe_type_agent_instrumentation(): - """Test @observe(as_type='agent') with the as_type-based approach.""" - langfuse = Langfuse() - api = get_api() - - trace_name = f"type_based_graph_test_{create_uuid()}" - - @observe(as_type="generation") - def start_agent(): - time.sleep(0.1) - return {"status": "started", "data": "initial_data"} - - @observe(as_type="retriever") - def process_agent(): - time.sleep(0.1) - return {"status": "processed", "data": "processed_data"} - - @observe(as_type="tool") - def tool_call(): - time.sleep(0.1) - return {"status": "intermediate", "data": "intermediate_data"} - - @observe(as_type="generation") - def end_agent(): - time.sleep(0.1) - return {"status": "completed", "data": "final_data"} - - # Run the workflow within a trace context - with langfuse.start_as_current_span(name="agent_workflow", as_type="agent"): - langfuse.update_current_trace(name=trace_name) - - start_result = start_agent() - process_result = process_agent() - tool_result = tool_call() - end_result = end_agent() - - _workflow_result = { - "start": start_result, - "process": process_result, - "tool": tool_result, - "end": end_result, - } - - langfuse.flush() - time.sleep(0.5) - - traces = api.trace.list(limit=50) - test_trace = None - for i, trace_data in enumerate(traces.data): - if trace_data.name == trace_name: - test_trace = trace_data - break - - assert test_trace is not None, f"Could not find trace with name {trace_name}" - - # Get the trace details including observations - trace_details = api.trace.get(test_trace.id) - all_observations = trace_details.observations - - agent_observations = [ - obs - for obs in all_observations - if obs.type - in [ - "agent", - "tool", - "retriever", - "chain", - "embedding", - "AGENT", - "TOOL", - "RETRIEVER", - "CHAIN", - "EMBEDDING", - "GENERATION", - "generation", - ] - ] - - assert ( - len(agent_observations) == 4 - ), f"Expected 4 observations, got {len(agent_observations)} out of {len(all_observations)} total observations" - - # for agent_obs in agent_observations: - # print( - # f"{agent_obs.name} ({agent_obs.type}): {agent_obs.start_time} - {agent_obs.end_time}" - # ) - - -def test_observe_type_parallel_tool_execution(): - """Test parallel tool execution where an agent starts multiple tools simultaneously. - - Creates a graph structure: - start_agent -> [tool_1, tool_2, tool_3] -> end_agent - """ - - langfuse = Langfuse() - api = get_api() - - trace_name = f"parallel_tools_test_{create_uuid()}" - - @observe(as_type="agent") - def start_agent(): - time.sleep(0.05) - return {"status": "tools_initiated", "tool_count": 3} - - @observe(as_type="tool") - def search_tool(): - time.sleep(0.2) - return {"tool": "search", "results": ["result1", "result2"]} - - @observe(as_type="tool") - def calculation_tool(): - time.sleep(0.15) - return {"tool": "calc", "result": 42} - - @observe(as_type="tool") - def api_tool(): - time.sleep(0.1) - return {"tool": "api", "data": {"status": "success"}} - - @observe(as_type="agent") - def end_agent(): - time.sleep(0.05) - return {"status": "completed", "summary": "all_tools_processed"} - - # Execute the parallel workflow - with langfuse.start_as_current_span(name="parallel_workflow", as_type="span"): - langfuse.update_current_trace(name=trace_name) - start_result = start_agent() - - # execute tools in parallel - but keep them in the same trace context - # we simulate parallel execution with staggered starts - - search_result = search_tool() - time.sleep(0.01) - calc_result = calculation_tool() - time.sleep(0.01) - api_result = api_tool() - - tool_results = { - "search": search_result, - "calculation": calc_result, - "api": api_result, - } - - end_result = end_agent() - - _workflow_result = { - "start": start_result, - "tools": tool_results, - "end": end_result, - } - - langfuse.flush() - time.sleep(0.5) - - traces = api.trace.list(limit=50) - test_trace = None - - for i, trace_data in enumerate(traces.data): - if trace_data.name == trace_name: - test_trace = trace_data - break - - assert test_trace is not None, f"Could not find trace with name {trace_name}" - - # Get trace details and filter observations - trace_details = api.trace.get(test_trace.id) - all_observations = trace_details.observations - - graph_observations = [ - obs - for obs in all_observations - if obs.type in ["agent", "tool", "AGENT", "TOOL"] - ] - - # Should have: start_agent (1) + 3 tools (3) + end_agent (1) = 5 total - expected_count = 5 - assert ( - len(graph_observations) == expected_count - ), f"Expected {expected_count} graph observations, got {len(graph_observations)} out of {len(all_observations)} total" - - # for obs in sorted(graph_observations, key=lambda x: x.start_time): - # print(f" {obs.name} ({obs.type}): {obs.start_time} - {obs.end_time}") - - agent_observations = [obs for obs in graph_observations if obs.type == "agent"] - tool_observations = [obs for obs in graph_observations if obs.type == "tool"] - - assert ( - len(agent_observations) == 2 - ), f"Expected 2 agent observations, got {len(agent_observations)}" - assert ( - len(tool_observations) == 3 - ), f"Expected 3 tool observations, got {len(tool_observations)}" From 0267755dc86ec018ffcdc2a17c4068d4f89f6b8a Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 15:17:58 +0200 Subject: [PATCH 38/66] a bit more clean --- langfuse/_client/client.py | 1 - langfuse/_client/observe.py | 1 - langfuse/_client/span.py | 1 - 3 files changed, 3 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index bbb580fd5..0f8353ccb 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -962,7 +962,6 @@ def _get_span_class( elif normalized_type == "span": return LangfuseSpan else: - # Default to LangfuseSpan for unrecognized types return LangfuseSpan @_agnosticcontextmanager diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index abc7ddc91..89758498e 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -265,7 +265,6 @@ async def async_wrapper(*args: Tuple[Any], **kwargs: Dict[str, Any]) -> Any: # Set public key in execution context for nested decorated functions with _set_current_public_key(public_key): langfuse_client = get_client(public_key=public_key) - context_manager: Optional[ Union[ _AgnosticContextManager[LangfuseGeneration], diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index acdbd474e..e5e2460e7 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -600,7 +600,6 @@ def update( if name: self._otel_span.update_name(name) - # Use same logic as __init__ to determine which attributes to create if self._observation_type in get_args(ObservationTypeGenerationLike): attributes = create_generation_attributes( input=processed_input, From 5aba0bae808d4d85fe482ee7cf5fcf69a48835bc Mon Sep 17 00:00:00 2001 From: Nimar Date: Mon, 18 Aug 2025 15:53:09 +0200 Subject: [PATCH 39/66] cleanup --- langfuse/_client/span.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index e5e2460e7..c968f820d 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -542,9 +542,6 @@ def _process_media_in_attribute( return data - # Add observation type tracking and unified update method - _observation_type: ObservationTypeLiteral - def update( self, *, @@ -685,8 +682,8 @@ def __init__( status_message: Optional status message for the span """ super().__init__( - as_type="span", otel_span=otel_span, + as_type="span", langfuse_client=langfuse_client, input=input, output=output, @@ -1044,7 +1041,6 @@ def create_event( ).end(end_time=timestamp), ) - # Generic child creation methods with overloads for type safety @overload def start_observation( self, From 14f73bd1dbae075ef03ed56ed642cc4fdb3e19ff Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 11:01:55 +0200 Subject: [PATCH 40/66] overload all the things --- langfuse/_client/client.py | 298 +++++++++++++++++++++++++------------ 1 file changed, 205 insertions(+), 93 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 0f8353ccb..c5f729078 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -397,46 +397,106 @@ def start_as_current_span( child_span.update(output="sub-result") ``` """ - if trace_context: - trace_id = trace_context.get("trace_id", None) - parent_span_id = trace_context.get("parent_span_id", None) + return self.start_as_current_observation( + trace_context=trace_context, + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + end_on_exit=end_on_exit, + ) - if trace_id: - remote_parent_span = self._create_remote_parent_span( - trace_id=trace_id, parent_span_id=parent_span_id - ) + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: ObservationTypeLiteralNoEvent = "span", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ]: + """Create a new observation of the specified type. - return cast( - _AgnosticContextManager[LangfuseSpan], - self._create_span_with_parent_context( - as_type="span", - name=name, - remote_parent_span=remote_parent_span, - parent=None, - end_on_exit=end_on_exit, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ), - ) + This method creates a new observation but does not set it as the current span in the + context. To create and use an observation within a context, use start_as_current_observation(). - return cast( - _AgnosticContextManager[LangfuseSpan], - self._start_as_current_otel_span_with_processed_media( - as_type="span", + Args: + trace_context: Optional context for connecting to an existing trace + name: Name of the observation + as_type: Type of observation to create (defaults to "span") + input: Input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the observation + version: Version identifier for the code or component + level: Importance level of the observation + status_message: Optional status message for the observation + completion_start_time: When the model started generating (for generation types) + model: Name/identifier of the AI model used (for generation types) + model_parameters: Parameters used for the model (for generation types) + usage_details: Token usage information (for generation types) + cost_details: Cost information (for generation types) + prompt: Associated prompt template (for generation types) + + Returns: + An observation object of the appropriate type that must be ended with .end() + """ + if as_type == "generation": + return self.start_generation( + trace_context=trace_context, name=name, - end_on_exit=end_on_exit, input=input, output=output, metadata=metadata, version=version, level=level, status_message=status_message, - ), - ) + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + else: + # For all other types, create a span and set the appropriate type + span = self.start_span( + trace_context=trace_context, + name=name, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ) + # Set the observation type on the span + span._observation_type = as_type + span._otel_span.set_attribute("langfuse.observation.type", as_type) + return span def start_generation( self, @@ -624,57 +684,23 @@ def start_as_current_generation( ) ``` """ - if trace_context: - trace_id = trace_context.get("trace_id", None) - parent_span_id = trace_context.get("parent_span_id", None) - - if trace_id: - remote_parent_span = self._create_remote_parent_span( - trace_id=trace_id, parent_span_id=parent_span_id - ) - - return cast( - _AgnosticContextManager[LangfuseGeneration], - self._create_span_with_parent_context( - as_type="generation", - name=name, - remote_parent_span=remote_parent_span, - parent=None, - end_on_exit=end_on_exit, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), - ) - - return cast( - _AgnosticContextManager[LangfuseGeneration], - self._start_as_current_otel_span_with_processed_media( - as_type="generation", - name=name, - end_on_exit=end_on_exit, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), + return self.start_as_current_observation( + trace_context=trace_context, + name=name, + as_type="generation", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + end_on_exit=end_on_exit, ) @overload @@ -721,9 +747,7 @@ def start_as_current_observation( *, trace_context: Optional[TraceContext] = None, name: str, - as_type: Literal[ - "agent", "tool", "chain", "retriever", "evaluator", "embedding", "guardrail" - ], + as_type: Literal["agent"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -731,15 +755,103 @@ def start_as_current_observation( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, end_on_exit: Optional[bool] = None, - ) -> Union[ - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], - ]: ... + ) -> _AgnosticContextManager[LangfuseAgent]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["tool"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseTool]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["chain"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseChain]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["retriever"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseRetriever]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["evaluator"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseEvaluator]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["embedding"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseEmbedding]: ... + + @overload + def start_as_current_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["guardrail"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + end_on_exit: Optional[bool] = None, + ) -> _AgnosticContextManager[LangfuseGuardrail]: ... def start_as_current_observation( self, From 55dce5bfae1c309e433176e404577d31eb8af4a4 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 11:20:25 +0200 Subject: [PATCH 41/66] overload --- langfuse/_client/client.py | 446 ++++++++++++++++++++++++++++--------- 1 file changed, 341 insertions(+), 105 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index c5f729078..97cbbca30 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -308,39 +308,10 @@ def start_span( span.end() ``` """ - if trace_context: - trace_id = trace_context.get("trace_id", None) - parent_span_id = trace_context.get("parent_span_id", None) - - if trace_id: - remote_parent_span = self._create_remote_parent_span( - trace_id=trace_id, parent_span_id=parent_span_id - ) - - with otel_trace_api.use_span( - cast(otel_trace_api.Span, remote_parent_span) - ): - otel_span = self._otel_tracer.start_span(name=name) - otel_span.set_attribute(LangfuseOtelSpanAttributes.AS_ROOT, True) - - return LangfuseSpan( - otel_span=otel_span, - langfuse_client=self, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ) - - otel_span = self._otel_tracer.start_span(name=name) - - return LangfuseSpan( - otel_span=otel_span, - langfuse_client=self, - environment=self._environment, + return self.start_observation( + trace_context=trace_context, + name=name, + as_type="span", input=input, output=output, metadata=metadata, @@ -410,6 +381,147 @@ def start_as_current_span( end_on_exit=end_on_exit, ) + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["generation"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> LangfuseGeneration: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["span"] = "span", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseSpan: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["agent"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseAgent: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["tool"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseTool: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["chain"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseChain: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["retriever"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseRetriever: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["evaluator"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseEvaluator: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["embedding"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseEmbedding: ... + + @overload + def start_observation( + self, + *, + trace_context: Optional[TraceContext] = None, + name: str, + as_type: Literal["guardrail"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> LangfuseGuardrail: ... + def start_observation( self, *, @@ -464,10 +576,90 @@ def start_observation( Returns: An observation object of the appropriate type that must be ended with .end() """ + if trace_context: + trace_id = trace_context.get("trace_id", None) + parent_span_id = trace_context.get("parent_span_id", None) + + if trace_id: + remote_parent_span = self._create_remote_parent_span( + trace_id=trace_id, parent_span_id=parent_span_id + ) + + with otel_trace_api.use_span( + cast(otel_trace_api.Span, remote_parent_span) + ): + otel_span = self._otel_tracer.start_span(name=name) + otel_span.set_attribute(LangfuseOtelSpanAttributes.AS_ROOT, True) + + return self._create_observation_from_otel_span( + otel_span=otel_span, + as_type=as_type, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + + otel_span = self._otel_tracer.start_span(name=name) + + return self._create_observation_from_otel_span( + otel_span=otel_span, + as_type=as_type, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + + def _create_observation_from_otel_span( + self, + *, + otel_span: otel_trace_api.Span, + as_type: ObservationTypeLiteralNoEvent, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + LangfuseGuardrail, + ]: + """Create the appropriate observation type from an OTEL span.""" if as_type == "generation": - return self.start_generation( - trace_context=trace_context, - name=name, + return LangfuseGeneration( + otel_span=otel_span, + langfuse_client=self, input=input, output=output, metadata=metadata, @@ -481,11 +673,24 @@ def start_observation( cost_details=cost_details, prompt=prompt, ) + elif as_type == "span": + return LangfuseSpan( + otel_span=otel_span, + langfuse_client=self, + environment=self._environment, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ) else: - # For all other types, create a span and set the appropriate type - span = self.start_span( - trace_context=trace_context, - name=name, + # For all other observation types (agent, tool, etc.), create a span and set the type + span = LangfuseSpan( + otel_span=otel_span, + langfuse_client=self, + environment=self._environment, input=input, output=output, metadata=metadata, @@ -566,43 +771,10 @@ def start_generation( generation.end() ``` """ - if trace_context: - trace_id = trace_context.get("trace_id", None) - parent_span_id = trace_context.get("parent_span_id", None) - - if trace_id: - remote_parent_span = self._create_remote_parent_span( - trace_id=trace_id, parent_span_id=parent_span_id - ) - - with otel_trace_api.use_span( - cast(otel_trace_api.Span, remote_parent_span) - ): - otel_span = self._otel_tracer.start_span(name=name) - otel_span.set_attribute(LangfuseOtelSpanAttributes.AS_ROOT, True) - - return LangfuseGeneration( - otel_span=otel_span, - langfuse_client=self, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ) - - otel_span = self._otel_tracer.start_span(name=name) - - return LangfuseGeneration( - otel_span=otel_span, - langfuse_client=self, + return self.start_observation( + trace_context=trace_context, + name=name, + as_type="generation", input=input, output=output, metadata=metadata, @@ -945,36 +1117,100 @@ def start_as_current_observation( generation.update(output=response) ``` """ - if as_type == "span": - return self.start_as_current_span( - trace_context=trace_context, - name=name, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - end_on_exit=end_on_exit, + if as_type == "generation": + if trace_context: + trace_id = trace_context.get("trace_id", None) + parent_span_id = trace_context.get("parent_span_id", None) + + if trace_id: + remote_parent_span = self._create_remote_parent_span( + trace_id=trace_id, parent_span_id=parent_span_id + ) + + return cast( + _AgnosticContextManager[LangfuseGeneration], + self._create_span_with_parent_context( + as_type="generation", + name=name, + remote_parent_span=remote_parent_span, + parent=None, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), + ) + + return cast( + _AgnosticContextManager[LangfuseGeneration], + self._start_as_current_otel_span_with_processed_media( + as_type="generation", + name=name, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), ) - if as_type == "generation": - return self.start_as_current_generation( - trace_context=trace_context, - name=name, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - end_on_exit=end_on_exit, + if as_type == "span": + if trace_context: + trace_id = trace_context.get("trace_id", None) + parent_span_id = trace_context.get("parent_span_id", None) + + if trace_id: + remote_parent_span = self._create_remote_parent_span( + trace_id=trace_id, parent_span_id=parent_span_id + ) + + return cast( + _AgnosticContextManager[LangfuseSpan], + self._create_span_with_parent_context( + as_type="span", + name=name, + remote_parent_span=remote_parent_span, + parent=None, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ), + ) + + return cast( + _AgnosticContextManager[LangfuseSpan], + self._start_as_current_otel_span_with_processed_media( + as_type="span", + name=name, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ), ) if trace_context: From 37c284b2fc46308ea00501f0e76160b608978b63 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 11:23:50 +0200 Subject: [PATCH 42/66] rename spanwrapper to observation wrapper --- langfuse/_client/span.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index c968f820d..a6d1552ab 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -5,7 +5,7 @@ creating, updating, and scoring various types of spans used in AI application tracing. Classes: -- LangfuseSpanWrapper: Abstract base class for all Langfuse spans +- LangfuseObservationWrapper: Abstract base class for all Langfuse spans - LangfuseSpan: Implementation for general-purpose spans - LangfuseGeneration: Specialized span implementation for LLM generations @@ -54,10 +54,10 @@ # Factory mapping for observation classes # Note: "event" is handled separately due to special instantiation logic # Populated after class definitions -_OBSERVATION_CLASS_MAP: Dict[str, Type["LangfuseSpanWrapper"]] = {} +_OBSERVATION_CLASS_MAP: Dict[str, Type["LangfuseObservationWrapper"]] = {} -class LangfuseSpanWrapper: +class LangfuseObservationWrapper: """Abstract base class for all Langfuse span types. This class provides common functionality for all Langfuse span types, including @@ -191,7 +191,7 @@ def __init__( {k: v for k, v in attributes.items() if v is not None} ) - def end(self, *, end_time: Optional[int] = None) -> "LangfuseSpanWrapper": + def end(self, *, end_time: Optional[int] = None) -> "LangfuseObservationWrapper": """End the span, marking it as completed. This method ends the wrapped OpenTelemetry span, marking the end of the @@ -217,7 +217,7 @@ def update_trace( metadata: Optional[Any] = None, tags: Optional[List[str]] = None, public: Optional[bool] = None, - ) -> "LangfuseSpanWrapper": + ) -> "LangfuseObservationWrapper": """Update the trace that this span belongs to. This method updates trace-level attributes of the trace that this span @@ -559,7 +559,7 @@ def update( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, **kwargs: Any, - ) -> "LangfuseSpanWrapper": + ) -> "LangfuseObservationWrapper": """Update this observation with new information. This method updates the observation with new information that becomes available @@ -646,11 +646,11 @@ def update( return self -class LangfuseSpan(LangfuseSpanWrapper): +class LangfuseSpan(LangfuseObservationWrapper): """Standard span implementation for general operations in Langfuse. This class represents a general-purpose span that can be used to trace - any operation in your application. It extends the base LangfuseSpanWrapper + any operation in your application. It extends the base LangfuseObservationWrapper with specific methods for creating child spans, generations, and updating span-specific attributes. """ @@ -1462,11 +1462,11 @@ def start_as_current_observation( # type: ignore[misc] ) -class LangfuseGeneration(LangfuseSpanWrapper): +class LangfuseGeneration(LangfuseObservationWrapper): """Specialized span implementation for AI model generations in Langfuse. This class represents a generation span specifically designed for tracking - AI/LLM operations. It extends the base LangfuseSpanWrapper with specialized + AI/LLM operations. It extends the base LangfuseObservationWrapper with specialized attributes for model details, token usage, and costs. """ @@ -1528,7 +1528,7 @@ def __init__( ) -class LangfuseEvent(LangfuseSpanWrapper): +class LangfuseEvent(LangfuseObservationWrapper): """Specialized span implementation for Langfuse Events.""" def __init__( @@ -1571,7 +1571,7 @@ def __init__( ) -class LangfuseAgent(LangfuseSpanWrapper): +class LangfuseAgent(LangfuseObservationWrapper): """Specialized span for agent observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1580,7 +1580,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseTool(LangfuseSpanWrapper): +class LangfuseTool(LangfuseObservationWrapper): """Specialized span for tool observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1589,7 +1589,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseChain(LangfuseSpanWrapper): +class LangfuseChain(LangfuseObservationWrapper): """Specialized span for chain observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1598,7 +1598,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseRetriever(LangfuseSpanWrapper): +class LangfuseRetriever(LangfuseObservationWrapper): """Specialized span for retriever observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1607,7 +1607,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseEmbedding(LangfuseSpanWrapper): +class LangfuseEmbedding(LangfuseObservationWrapper): """Specialized span for embedding observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1616,7 +1616,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseEvaluator(LangfuseSpanWrapper): +class LangfuseEvaluator(LangfuseObservationWrapper): """Specialized span for evaluator observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: @@ -1625,7 +1625,7 @@ def __init__(self, **kwargs: Any) -> None: super().__init__(**kwargs) -class LangfuseGuardrail(LangfuseSpanWrapper): +class LangfuseGuardrail(LangfuseObservationWrapper): """Specialized span for guardrail observations in agentic workflows.""" def __init__(self, **kwargs: Any) -> None: From c08055d4f451ced70c9f5de5f2126c6a7b23181e Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 11:46:27 +0200 Subject: [PATCH 43/66] don't update events --- langfuse/_client/span.py | 30 ++++++++++++++++++++++++++++++ tests/test_otel.py | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index a6d1552ab..3009fad62 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1570,6 +1570,36 @@ def __init__( status_message=status_message, ) + def update( + self, + *, + name: Optional[str] = None, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + **kwargs: Any, + ) -> "LangfuseObservationWrapper": + """Update is not allowed for LangfuseEvent because events cannot be updated. + + This method logs a warning and returns self without making changes. + + Returns: + self: Returns the unchanged LangfuseEvent instance + """ + langfuse_logger.warning( + "Attempted to update LangfuseEvent observation. Events cannot be updated after creation." + ) + return self + class LangfuseAgent(LangfuseObservationWrapper): """Specialized span for agent observations in agentic workflows.""" diff --git a/tests/test_otel.py b/tests/test_otel.py index 05ffbb026..5f6f1caca 100644 --- a/tests/test_otel.py +++ b/tests/test_otel.py @@ -628,12 +628,6 @@ def test_start_as_current_observation_types(self, langfuse_client, memory_export LangfuseOtelSpanAttributes.OBSERVATION_TYPE ) - # Debug: print all attributes for this span - print( - f"Span {expected_name} attributes: {list(span_data['attributes'].keys())}" - ) - print(f"Expected: {expected_otel_type}, Actual: {actual_type}") - assert ( actual_type == expected_otel_type ), f"Expected observation type {expected_otel_type}, got {actual_type}" @@ -3036,3 +3030,33 @@ def test_different_seeds_produce_different_ids(self, langfuse_client): # All observation IDs should be unique assert len(set(observation_ids)) == len(seeds) + + def test_langfuse_event_update_immutability(self, langfuse_client, memory_exporter, caplog): + """Test that LangfuseEvent.update() logs a warning and does nothing.""" + import logging + + parent_span = langfuse_client.start_span(name="parent-span") + + event = parent_span.start_observation( + name="test-event", + as_type="event", + input={"original": "input"}, + ) + + # Try to update the event and capture warning logs + with caplog.at_level(logging.WARNING, logger='langfuse._client.span'): + result = event.update( + name="updated_name", + input={"updated": "input"}, + output={"updated": "output"}, + metadata={"updated": "metadata"} + ) + + # Verify warning was logged + assert "Attempted to update LangfuseEvent observation" in caplog.text + assert "Events are immutable and cannot be updated after creation" in caplog.text + + # Verify the method returned self unchanged + assert result is event + + parent_span.end() From 717c302e0eec400e18ca994a41d2cf0fbbe64f33 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 11:55:52 +0200 Subject: [PATCH 44/66] fix test --- tests/test_otel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_otel.py b/tests/test_otel.py index 5f6f1caca..185e2fd38 100644 --- a/tests/test_otel.py +++ b/tests/test_otel.py @@ -3054,7 +3054,7 @@ def test_langfuse_event_update_immutability(self, langfuse_client, memory_export # Verify warning was logged assert "Attempted to update LangfuseEvent observation" in caplog.text - assert "Events are immutable and cannot be updated after creation" in caplog.text + assert "Events cannot be updated after creation" in caplog.text # Verify the method returned self unchanged assert result is event From dc7d7ff016ac1ffc58595107d9fdd695e4eaea62 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 18:54:58 +0200 Subject: [PATCH 45/66] fix span --- langfuse/_client/attributes.py | 2 +- langfuse/_client/span.py | 868 ++++++++++++++++----------------- langfuse/openai.py | 6 +- 3 files changed, 439 insertions(+), 437 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index 284db2b50..d0ee06a44 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -95,7 +95,7 @@ def create_span_attributes( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, version: Optional[str] = None, - observation_type: Optional[Literal["span", "guardrail"]] = "span", + observation_type: Optional[Literal["span", "guardrail", "event"]] = "span", ) -> dict: attributes = { LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 3009fad62..cc4f5082d 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -180,8 +180,8 @@ def __init__( level=level, status_message=status_message, observation_type=cast( - Optional[Literal["span", "guardrail"]], - as_type if as_type in ["span", "guardrail"] else None, + Optional[Literal["span", "guardrail", "event"]], + as_type if as_type in ["span", "guardrail", "event"] else None, ), ) @@ -634,9 +634,9 @@ def update( level=level, status_message=status_message, observation_type=cast( - Optional[Literal["span", "guardrail"]], + Optional[Literal["span", "guardrail", "event"]], self._observation_type - if self._observation_type in ["span", "guardrail"] + if self._observation_type in ["span", "guardrail", "event"] else None, ), ) @@ -645,174 +645,66 @@ def update( return self - -class LangfuseSpan(LangfuseObservationWrapper): - """Standard span implementation for general operations in Langfuse. - - This class represents a general-purpose span that can be used to trace - any operation in your application. It extends the base LangfuseObservationWrapper - with specific methods for creating child spans, generations, and updating - span-specific attributes. - """ - - def __init__( + @overload + def start_observation( self, *, - otel_span: otel_trace_api.Span, - langfuse_client: "Langfuse", + name: str, + as_type: Literal["span"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, - environment: Optional[str] = None, version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - ): - """Initialize a new LangfuseSpan. - - Args: - otel_span: The OpenTelemetry span to wrap - langfuse_client: Reference to the parent Langfuse client - input: Input data for the span (any JSON-serializable object) - output: Output data from the span (any JSON-serializable object) - metadata: Additional metadata to associate with the span - environment: The tracing environment - version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span - """ - super().__init__( - otel_span=otel_span, - as_type="span", - langfuse_client=langfuse_client, - input=input, - output=output, - metadata=metadata, - environment=environment, - version=version, - level=level, - status_message=status_message, - ) + ) -> "LangfuseSpan": ... - def start_span( + @overload + def start_observation( self, + *, name: str, + as_type: Literal["generation"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - ) -> "LangfuseSpan": - """Create a new child span. - - This method creates a new child span with this span as the parent. - Unlike start_as_current_span(), this method does not set the new span - as the current span in the context. - - Args: - name: Name of the span (e.g., function or operation name) - input: Input data for the operation - output: Output data from the operation - metadata: Additional metadata to associate with the span - version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span - - Returns: - A new LangfuseSpan that must be ended with .end() when complete - - Example: - ```python - parent_span = langfuse.start_span(name="process-request") - try: - # Create a child span - child_span = parent_span.start_span(name="validate-input") - try: - # Do validation work - validation_result = validate(request_data) - child_span.update(output=validation_result) - finally: - child_span.end() - - # Continue with parent span - result = process_validated_data(validation_result) - parent_span.update(output=result) - finally: - parent_span.end() - ``` - """ - return self.start_observation( - name=name, - as_type="span", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ) + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseGeneration": ... - def start_as_current_span( + @overload + def start_observation( self, *, name: str, + as_type: Literal["agent"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - ) -> _AgnosticContextManager["LangfuseSpan"]: - """Create a new child span and set it as the current span in a context manager. - - This method creates a new child span and sets it as the current span within - a context manager. It should be used with a 'with' statement to automatically - manage the span's lifecycle. - - Args: - name: Name of the span (e.g., function or operation name) - input: Input data for the operation - output: Output data from the operation - metadata: Additional metadata to associate with the span - version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span - - Returns: - A context manager that yields a new LangfuseSpan - - Example: - ```python - with langfuse.start_as_current_span(name="process-request") as parent_span: - # Parent span is active here - - # Create a child span with context management - with parent_span.start_as_current_span(name="validate-input") as child_span: - # Child span is active here - validation_result = validate(request_data) - child_span.update(output=validation_result) - - # Back to parent span context - result = process_validated_data(validation_result) - parent_span.update(output=result) - ``` - """ - return self.start_as_current_observation( - name=name, - as_type="span", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ) + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseAgent": ... - def start_generation( + @overload + def start_observation( self, *, name: str, + as_type: Literal["tool"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -825,85 +717,14 @@ def start_generation( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - ) -> "LangfuseGeneration": - """Create a new child generation span. - - This method creates a new child generation span with this span as the parent. - Generation spans are specialized for AI/LLM operations and include additional - fields for model information, usage stats, and costs. - - Unlike start_as_current_generation(), this method does not set the new span - as the current span in the context. - - Args: - name: Name of the generation operation - input: Input data for the model (e.g., prompts) - output: Output from the model (e.g., completions) - metadata: Additional metadata to associate with the generation - version: Version identifier for the model or component - level: Importance level of the generation (info, warning, error) - status_message: Optional status message for the generation - completion_start_time: When the model started generating the response - model: Name/identifier of the AI model used (e.g., "gpt-4") - model_parameters: Parameters used for the model (e.g., temperature, max_tokens) - usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) - cost_details: Cost information for the model call - prompt: Associated prompt template from Langfuse prompt management - - Returns: - A new LangfuseGeneration that must be ended with .end() when complete - - Example: - ```python - span = langfuse.start_span(name="process-query") - try: - # Create a generation child span - generation = span.start_generation( - name="generate-answer", - model="gpt-4", - input={"prompt": "Explain quantum computing"} - ) - try: - # Call model API - response = llm.generate(...) - - generation.update( - output=response.text, - usage_details={ - "prompt_tokens": response.usage.prompt_tokens, - "completion_tokens": response.usage.completion_tokens - } - ) - finally: - generation.end() - - # Continue with parent span - span.update(output={"answer": response.text, "source": "gpt-4"}) - finally: - span.end() - ``` - """ - return self.start_observation( - name=name, - as_type="generation", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ) + ) -> "LangfuseTool": ... - def start_as_current_generation( + @overload + def start_observation( self, *, name: str, + as_type: Literal["chain"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -916,224 +737,7 @@ def start_as_current_generation( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - ) -> _AgnosticContextManager["LangfuseGeneration"]: - """Create a new child generation span and set it as the current span in a context manager. - - This method creates a new child generation span and sets it as the current span - within a context manager. Generation spans are specialized for AI/LLM operations - and include additional fields for model information, usage stats, and costs. - - Args: - name: Name of the generation operation - input: Input data for the model (e.g., prompts) - output: Output from the model (e.g., completions) - metadata: Additional metadata to associate with the generation - version: Version identifier for the model or component - level: Importance level of the generation (info, warning, error) - status_message: Optional status message for the generation - completion_start_time: When the model started generating the response - model: Name/identifier of the AI model used (e.g., "gpt-4") - model_parameters: Parameters used for the model (e.g., temperature, max_tokens) - usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) - cost_details: Cost information for the model call - prompt: Associated prompt template from Langfuse prompt management - - Returns: - A context manager that yields a new LangfuseGeneration - - Example: - ```python - with langfuse.start_as_current_span(name="process-request") as span: - # Prepare data - query = preprocess_user_query(user_input) - - # Create a generation span with context management - with span.start_as_current_generation( - name="generate-answer", - model="gpt-4", - input={"query": query} - ) as generation: - # Generation span is active here - response = llm.generate(query) - - # Update with results - generation.update( - output=response.text, - usage_details={ - "prompt_tokens": response.usage.prompt_tokens, - "completion_tokens": response.usage.completion_tokens - } - ) - - # Back to parent span context - span.update(output={"answer": response.text, "source": "gpt-4"}) - ``` - """ - return cast( - _AgnosticContextManager["LangfuseGeneration"], - self.start_as_current_observation( - name=name, - as_type="generation", - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), - ) - - def create_event( - self, - *, - name: str, - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - ) -> "LangfuseEvent": - """Create a new Langfuse observation of type 'EVENT'. - - Args: - name: Name of the span (e.g., function or operation name) - input: Input data for the operation (can be any JSON-serializable object) - output: Output data from the operation (can be any JSON-serializable object) - metadata: Additional metadata to associate with the span - version: Version identifier for the code or component - level: Importance level of the span (info, warning, error) - status_message: Optional status message for the span - - Returns: - The LangfuseEvent object - - Example: - ```python - event = langfuse.create_event(name="process-event") - ``` - """ - timestamp = time_ns() - - with otel_trace_api.use_span(self._otel_span): - new_otel_span = self._langfuse_client._otel_tracer.start_span( - name=name, start_time=timestamp - ) - - return cast( - "LangfuseEvent", - LangfuseEvent( - otel_span=new_otel_span, - langfuse_client=self._langfuse_client, - input=input, - output=output, - metadata=metadata, - environment=self._environment, - version=version, - level=level, - status_message=status_message, - ).end(end_time=timestamp), - ) - - @overload - def start_observation( - self, - *, - name: str, - as_type: Literal["span"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - ) -> "LangfuseSpan": ... - - @overload - def start_observation( - self, - *, - name: str, - as_type: Literal["generation"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ) -> "LangfuseGeneration": ... - - @overload - def start_observation( - self, - *, - name: str, - as_type: Literal["agent"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ) -> "LangfuseAgent": ... - - @overload - def start_observation( - self, - *, - name: str, - as_type: Literal["tool"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ) -> "LangfuseTool": ... - - @overload - def start_observation( - self, - *, - name: str, - as_type: Literal["chain"], - input: Optional[Any] = None, - output: Optional[Any] = None, - metadata: Optional[Any] = None, - version: Optional[str] = None, - level: Optional[SpanLevel] = None, - status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, - ) -> "LangfuseChain": ... + ) -> "LangfuseChain": ... @overload def start_observation( @@ -1462,6 +1066,402 @@ def start_as_current_observation( # type: ignore[misc] ) +class LangfuseSpan(LangfuseObservationWrapper): + """Standard span implementation for general operations in Langfuse. + + This class represents a general-purpose span that can be used to trace + any operation in your application. It extends the base LangfuseObservationWrapper + with specific methods for creating child spans, generations, and updating + span-specific attributes. + """ + + def __init__( + self, + *, + otel_span: otel_trace_api.Span, + langfuse_client: "Langfuse", + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + environment: Optional[str] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ): + """Initialize a new LangfuseSpan. + + Args: + otel_span: The OpenTelemetry span to wrap + langfuse_client: Reference to the parent Langfuse client + input: Input data for the span (any JSON-serializable object) + output: Output data from the span (any JSON-serializable object) + metadata: Additional metadata to associate with the span + environment: The tracing environment + version: Version identifier for the code or component + level: Importance level of the span (info, warning, error) + status_message: Optional status message for the span + """ + super().__init__( + otel_span=otel_span, + as_type="span", + langfuse_client=langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=environment, + version=version, + level=level, + status_message=status_message, + ) + + def start_span( + self, + name: str, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> "LangfuseSpan": + """Create a new child span. + + This method creates a new child span with this span as the parent. + Unlike start_as_current_span(), this method does not set the new span + as the current span in the context. + + Args: + name: Name of the span (e.g., function or operation name) + input: Input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the span + version: Version identifier for the code or component + level: Importance level of the span (info, warning, error) + status_message: Optional status message for the span + + Returns: + A new LangfuseSpan that must be ended with .end() when complete + + Example: + ```python + parent_span = langfuse.start_span(name="process-request") + try: + # Create a child span + child_span = parent_span.start_span(name="validate-input") + try: + # Do validation work + validation_result = validate(request_data) + child_span.update(output=validation_result) + finally: + child_span.end() + + # Continue with parent span + result = process_validated_data(validation_result) + parent_span.update(output=result) + finally: + parent_span.end() + ``` + """ + return self.start_observation( + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ) + + def start_as_current_span( + self, + *, + name: str, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseSpan"]: + """Create a new child span and set it as the current span in a context manager. + + This method creates a new child span and sets it as the current span within + a context manager. It should be used with a 'with' statement to automatically + manage the span's lifecycle. + + Args: + name: Name of the span (e.g., function or operation name) + input: Input data for the operation + output: Output data from the operation + metadata: Additional metadata to associate with the span + version: Version identifier for the code or component + level: Importance level of the span (info, warning, error) + status_message: Optional status message for the span + + Returns: + A context manager that yields a new LangfuseSpan + + Example: + ```python + with langfuse.start_as_current_span(name="process-request") as parent_span: + # Parent span is active here + + # Create a child span with context management + with parent_span.start_as_current_span(name="validate-input") as child_span: + # Child span is active here + validation_result = validate(request_data) + child_span.update(output=validation_result) + + # Back to parent span context + result = process_validated_data(validation_result) + parent_span.update(output=result) + ``` + """ + return self.start_as_current_observation( + name=name, + as_type="span", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + ) + + def start_generation( + self, + *, + name: str, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> "LangfuseGeneration": + """Create a new child generation span. + + This method creates a new child generation span with this span as the parent. + Generation spans are specialized for AI/LLM operations and include additional + fields for model information, usage stats, and costs. + + Unlike start_as_current_generation(), this method does not set the new span + as the current span in the context. + + Args: + name: Name of the generation operation + input: Input data for the model (e.g., prompts) + output: Output from the model (e.g., completions) + metadata: Additional metadata to associate with the generation + version: Version identifier for the model or component + level: Importance level of the generation (info, warning, error) + status_message: Optional status message for the generation + completion_start_time: When the model started generating the response + model: Name/identifier of the AI model used (e.g., "gpt-4") + model_parameters: Parameters used for the model (e.g., temperature, max_tokens) + usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) + cost_details: Cost information for the model call + prompt: Associated prompt template from Langfuse prompt management + + Returns: + A new LangfuseGeneration that must be ended with .end() when complete + + Example: + ```python + span = langfuse.start_span(name="process-query") + try: + # Create a generation child span + generation = span.start_generation( + name="generate-answer", + model="gpt-4", + input={"prompt": "Explain quantum computing"} + ) + try: + # Call model API + response = llm.generate(...) + + generation.update( + output=response.text, + usage_details={ + "prompt_tokens": response.usage.prompt_tokens, + "completion_tokens": response.usage.completion_tokens + } + ) + finally: + generation.end() + + # Continue with parent span + span.update(output={"answer": response.text, "source": "gpt-4"}) + finally: + span.end() + ``` + """ + return self.start_observation( + name=name, + as_type="generation", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ) + + def start_as_current_generation( + self, + *, + name: str, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> _AgnosticContextManager["LangfuseGeneration"]: + """Create a new child generation span and set it as the current span in a context manager. + + This method creates a new child generation span and sets it as the current span + within a context manager. Generation spans are specialized for AI/LLM operations + and include additional fields for model information, usage stats, and costs. + + Args: + name: Name of the generation operation + input: Input data for the model (e.g., prompts) + output: Output from the model (e.g., completions) + metadata: Additional metadata to associate with the generation + version: Version identifier for the model or component + level: Importance level of the generation (info, warning, error) + status_message: Optional status message for the generation + completion_start_time: When the model started generating the response + model: Name/identifier of the AI model used (e.g., "gpt-4") + model_parameters: Parameters used for the model (e.g., temperature, max_tokens) + usage_details: Token usage information (e.g., prompt_tokens, completion_tokens) + cost_details: Cost information for the model call + prompt: Associated prompt template from Langfuse prompt management + + Returns: + A context manager that yields a new LangfuseGeneration + + Example: + ```python + with langfuse.start_as_current_span(name="process-request") as span: + # Prepare data + query = preprocess_user_query(user_input) + + # Create a generation span with context management + with span.start_as_current_generation( + name="generate-answer", + model="gpt-4", + input={"query": query} + ) as generation: + # Generation span is active here + response = llm.generate(query) + + # Update with results + generation.update( + output=response.text, + usage_details={ + "prompt_tokens": response.usage.prompt_tokens, + "completion_tokens": response.usage.completion_tokens + } + ) + + # Back to parent span context + span.update(output={"answer": response.text, "source": "gpt-4"}) + ``` + """ + return cast( + _AgnosticContextManager["LangfuseGeneration"], + self.start_as_current_observation( + name=name, + as_type="generation", + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, + completion_start_time=completion_start_time, + model=model, + model_parameters=model_parameters, + usage_details=usage_details, + cost_details=cost_details, + prompt=prompt, + ), + ) + + def create_event( + self, + *, + name: str, + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> "LangfuseEvent": + """Create a new Langfuse observation of type 'EVENT'. + + Args: + name: Name of the span (e.g., function or operation name) + input: Input data for the operation (can be any JSON-serializable object) + output: Output data from the operation (can be any JSON-serializable object) + metadata: Additional metadata to associate with the span + version: Version identifier for the code or component + level: Importance level of the span (info, warning, error) + status_message: Optional status message for the span + + Returns: + The LangfuseEvent object + + Example: + ```python + event = langfuse.create_event(name="process-event") + ``` + """ + timestamp = time_ns() + + with otel_trace_api.use_span(self._otel_span): + new_otel_span = self._langfuse_client._otel_tracer.start_span( + name=name, start_time=timestamp + ) + + return cast( + "LangfuseEvent", + LangfuseEvent( + otel_span=new_otel_span, + langfuse_client=self._langfuse_client, + input=input, + output=output, + metadata=metadata, + environment=self._environment, + version=version, + level=level, + status_message=status_message, + ).end(end_time=timestamp), + ) + + class LangfuseGeneration(LangfuseObservationWrapper): """Specialized span implementation for AI model generations in Langfuse. diff --git a/langfuse/openai.py b/langfuse/openai.py index 96ba14a0c..abd1b47c7 100644 --- a/langfuse/openai.py +++ b/langfuse/openai.py @@ -729,7 +729,8 @@ def _wrap( langfuse_data = _get_langfuse_data_from_kwargs(open_ai_resource, langfuse_args) langfuse_client = get_client(public_key=langfuse_args["langfuse_public_key"]) - generation = langfuse_client.start_generation( + generation = langfuse_client.start_observation( + as_type="generation", name=langfuse_data["name"], input=langfuse_data.get("input", None), metadata=langfuse_data.get("metadata", None), @@ -792,7 +793,8 @@ async def _wrap_async( langfuse_data = _get_langfuse_data_from_kwargs(open_ai_resource, langfuse_args) langfuse_client = get_client(public_key=langfuse_args["langfuse_public_key"]) - generation = langfuse_client.start_generation( + generation = langfuse_client.start_observation( + as_type="generation", name=langfuse_data["name"], input=langfuse_data.get("input", None), metadata=langfuse_data.get("metadata", None), From b6b1b01eaf2fa70b078c1cbbb3dbf3abfbab8a82 Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 19:08:35 +0200 Subject: [PATCH 46/66] fix test --- tests/test_otel.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_otel.py b/tests/test_otel.py index 185e2fd38..fd29ce671 100644 --- a/tests/test_otel.py +++ b/tests/test_otel.py @@ -102,7 +102,6 @@ def mock_init(self, **kwargs): @pytest.fixture def langfuse_client(self, monkeypatch, tracer_provider, mock_processor_init): """Create a mocked Langfuse client for testing.""" - # Set environment variables monkeypatch.setenv("LANGFUSE_PUBLIC_KEY", "test-public-key") monkeypatch.setenv("LANGFUSE_SECRET_KEY", "test-secret-key") @@ -3031,7 +3030,7 @@ def test_different_seeds_produce_different_ids(self, langfuse_client): # All observation IDs should be unique assert len(set(observation_ids)) == len(seeds) - def test_langfuse_event_update_immutability(self, langfuse_client, memory_exporter, caplog): + def test_langfuse_event_update_immutability(self, langfuse_client, caplog): """Test that LangfuseEvent.update() logs a warning and does nothing.""" import logging @@ -3044,12 +3043,12 @@ def test_langfuse_event_update_immutability(self, langfuse_client, memory_export ) # Try to update the event and capture warning logs - with caplog.at_level(logging.WARNING, logger='langfuse._client.span'): + with caplog.at_level(logging.WARNING, logger="langfuse._client.span"): result = event.update( name="updated_name", input={"updated": "input"}, output={"updated": "output"}, - metadata={"updated": "metadata"} + metadata={"updated": "metadata"}, ) # Verify warning was logged From e53723159162c1af0779804288e576612a8d403d Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 19:41:11 +0200 Subject: [PATCH 47/66] langchain --- langfuse/langchain/CallbackHandler.py | 129 ++++++++++++++++++++++---- tests/test_datasets.py | 2 +- tests/test_langchain.py | 2 +- 3 files changed, 113 insertions(+), 20 deletions(-) diff --git a/langfuse/langchain/CallbackHandler.py b/langfuse/langchain/CallbackHandler.py index 03e73c3f2..7f6196670 100644 --- a/langfuse/langchain/CallbackHandler.py +++ b/langfuse/langchain/CallbackHandler.py @@ -3,7 +3,15 @@ import pydantic from langfuse._client.get_client import get_client -from langfuse._client.span import LangfuseGeneration, LangfuseSpan +from langfuse._client.span import ( + LangfuseGeneration, + LangfuseSpan, + LangfuseAgent, + LangfuseChain, + LangfuseTool, + LangfuseRetriever, + LangfuseObservationWrapper, +) from langfuse.logger import langfuse_logger try: @@ -59,7 +67,17 @@ class LangchainCallbackHandler(LangchainBaseCallbackHandler): def __init__(self, *, public_key: Optional[str] = None) -> None: self.client = get_client(public_key=public_key) - self.runs: Dict[UUID, Union[LangfuseSpan, LangfuseGeneration]] = {} + self.runs: Dict[ + UUID, + Union[ + LangfuseSpan, + LangfuseGeneration, + LangfuseAgent, + LangfuseChain, + LangfuseTool, + LangfuseRetriever, + ], + ] = {} self.prompt_to_parent_run_map: Dict[UUID, Any] = {} self.updated_completion_start_time_memo: Set[UUID] = set() @@ -87,6 +105,49 @@ def on_llm_new_token( self.updated_completion_start_time_memo.add(run_id) + def _get_observation_type_from_serialized( + self, serialized: Optional[Dict[str, Any]], callback_type: str, **kwargs: Any + ) -> Union[ + Literal["tool"], + Literal["retriever"], + Literal["generation"], + Literal["agent"], + Literal["chain"], + Literal["span"], + ]: + """Determine Langfuse observation type from LangChain component. + + Args: + serialized: LangChain's serialized component dict + callback_type: The type of callback (e.g., "chain", "tool", "retriever", "llm") + **kwargs: Additional keyword arguments from the callback + + Returns: + The appropriate Langfuse observation type string + """ + # Direct mappings based on callback type + if callback_type == "tool": + return "tool" + elif callback_type == "retriever": + return "retriever" + elif callback_type == "llm": + return "generation" + elif callback_type == "chain": + # Detect if it's an agent by examining class path or name + if serialized and "id" in serialized: + class_path = serialized["id"] + if any("agent" in part.lower() for part in class_path): + return "agent" + + # Check name for agent-related keywords + name = self.get_langchain_run_name(serialized, **kwargs) + if "agent" in name.lower(): + return "agent" + + return "chain" + + return "span" + def get_langchain_run_name( self, serialized: Optional[Dict[str, Any]], **kwargs: Any ) -> str: @@ -196,9 +257,14 @@ def on_chain_start( span_metadata = self.__join_tags_and_metadata(tags, metadata) span_level = "DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None + observation_type = self._get_observation_type_from_serialized( + serialized, "chain", **kwargs + ) + if parent_run_id is None: - span = self.client.start_span( + span = self.client.start_observation( name=span_name, + as_type=observation_type, metadata=span_metadata, input=inputs, level=cast( @@ -212,9 +278,12 @@ def on_chain_start( self.runs[run_id] = span else: self.runs[run_id] = cast( - LangfuseSpan, self.runs[parent_run_id] - ).start_span( + # TODO: make this more precise (can be chain or agent here) + LangfuseObservationWrapper, + self.runs[parent_run_id], + ).start_observation( name=span_name, + as_type=observation_type, metadata=span_metadata, input=inputs, level=cast( @@ -442,8 +511,6 @@ def on_tool_start( "on_tool_start", run_id, parent_run_id, input_str=input_str ) - if parent_run_id is None or parent_run_id not in self.runs: - raise Exception("parent run not found") meta = self.__join_tags_and_metadata(tags, metadata) if not meta: @@ -453,13 +520,31 @@ def on_tool_start( {key: value for key, value in kwargs.items() if value is not None} ) - self.runs[run_id] = cast(LangfuseSpan, self.runs[parent_run_id]).start_span( - name=self.get_langchain_run_name(serialized, **kwargs), - input=input_str, - metadata=meta, - level="DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None, + observation_type = self._get_observation_type_from_serialized( + serialized, "tool", **kwargs ) + if parent_run_id is None or parent_run_id not in self.runs: + # Create root observation for direct tool calls + self.runs[run_id] = self.client.start_observation( + name=self.get_langchain_run_name(serialized, **kwargs), + as_type=observation_type, + input=input_str, + metadata=meta, + level="DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None, + ) + else: + # Create child observation for tools within chains/agents + self.runs[run_id] = cast( + LangfuseChain, self.runs[parent_run_id] + ).start_observation( + name=self.get_langchain_run_name(serialized, **kwargs), + as_type=observation_type, + input=input_str, + metadata=meta, + level="DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None, + ) + except Exception as e: langfuse_logger.exception(e) @@ -482,9 +567,14 @@ def on_retriever_start( span_metadata = self.__join_tags_and_metadata(tags, metadata) span_level = "DEBUG" if tags and LANGSMITH_TAG_HIDDEN in tags else None + observation_type = self._get_observation_type_from_serialized( + serialized, "retriever", **kwargs + ) + if parent_run_id is None: - self.runs[run_id] = self.client.start_span( + self.runs[run_id] = self.client.start_observation( name=span_name, + as_type=observation_type, metadata=span_metadata, input=query, level=cast( @@ -494,9 +584,10 @@ def on_retriever_start( ) else: self.runs[run_id] = cast( - LangfuseSpan, self.runs[parent_run_id] - ).start_span( + LangfuseRetriever, self.runs[parent_run_id] + ).start_observation( name=span_name, + as_type=observation_type, input=query, metadata=span_metadata, level=cast( @@ -625,10 +716,12 @@ def __on_llm_action( if parent_run_id is not None and parent_run_id in self.runs: self.runs[run_id] = cast( - LangfuseSpan, self.runs[parent_run_id] - ).start_generation(**content) # type: ignore + LangfuseGeneration, self.runs[parent_run_id] + ).start_observation(as_type="generation", **content) # type: ignore else: - self.runs[run_id] = self.client.start_generation(**content) # type: ignore + self.runs[run_id] = self.client.start_observation( + as_type="generation", **content + ) # type: ignore self.last_trace_id = self.runs[run_id].trace_id diff --git a/tests/test_datasets.py b/tests/test_datasets.py index 535625918..7217c0a8d 100644 --- a/tests/test_datasets.py +++ b/tests/test_datasets.py @@ -319,7 +319,7 @@ def sorted_dependencies_from_trace(trace): if len(sorted_observations) >= 2: assert sorted_observations[1].name == "RunnableSequence" - assert sorted_observations[1].type == "SPAN" + assert sorted_observations[1].type == "CHAIN" assert sorted_observations[1].input is not None assert sorted_observations[1].output is not None assert sorted_observations[1].input != "" diff --git a/tests/test_langchain.py b/tests/test_langchain.py index 71b0cb5f1..8c2cf27c4 100644 --- a/tests/test_langchain.py +++ b/tests/test_langchain.py @@ -60,7 +60,7 @@ def test_callback_generated_from_trace_chain(): langchain_span = list( filter( - lambda o: o.type == "SPAN" and o.name == "LLMChain", + lambda o: o.type == "CHAIN" and o.name == "LLMChain", trace.observations, ) )[0] From f7481d65580fd0711d64a17a1f27f2c3017ae2ba Mon Sep 17 00:00:00 2001 From: Nimar Date: Tue, 19 Aug 2025 19:51:59 +0200 Subject: [PATCH 48/66] formatting --- tests/test_langchain.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_langchain.py b/tests/test_langchain.py index 8c2cf27c4..fc4723bad 100644 --- a/tests/test_langchain.py +++ b/tests/test_langchain.py @@ -458,11 +458,11 @@ def test_agent_executor_chain(): prompt = PromptTemplate.from_template(""" Answer the following questions as best you can. You have access to the following tools: - + {tools} - + Use the following format: - + Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] @@ -471,9 +471,9 @@ def test_agent_executor_chain(): ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question - + Begin! - + Question: {input} Thought:{agent_scratchpad} """) @@ -558,7 +558,7 @@ def _identifying_params(self) -> Mapping[str, Any]: template = """You are a play critic from the New York Times. Given the synopsis of play, it is your job to write a review for that play. - + Play Synopsis: {synopsis} Review from a New York Times play critic of the above play:""" @@ -604,9 +604,9 @@ def test_openai_instruct_usage(): runnable_chain: Runnable = ( PromptTemplate.from_template( """Answer the question based only on the following context: - + Question: {question} - + Answer in the following language: {language} """ ) From 0206b4e925e53a2d1e745b529143e65e08fd1283 Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 20 Aug 2025 11:04:04 +0200 Subject: [PATCH 49/66] add langchain test --- tests/test_langchain.py | 88 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/test_langchain.py b/tests/test_langchain.py index fc4723bad..e869119dc 100644 --- a/tests/test_langchain.py +++ b/tests/test_langchain.py @@ -1353,3 +1353,91 @@ def test_cached_token_usage(): ) < 0.0001 ) + + +def test_langchain_automatic_observation_types(): + """Test that LangChain components automatically get correct observation types: + AGENT, TOOL, GENERATION, RETRIEVER, CHAIN""" + langfuse = Langfuse() + + with langfuse.start_as_current_span(name="observation_types_test_agent") as span: + trace_id = span.trace_id + handler = CallbackHandler() + + from langchain.agents import AgentExecutor, create_react_agent + from langchain.tools import tool + + # for type TOOL + @tool + def test_tool(x: str) -> str: + """Process input string.""" + return f"processed {x}" + + # for type GENERATION + llm = ChatOpenAI(temperature=0) + tools = [test_tool] + + prompt = PromptTemplate.from_template(""" + Answer: {input} + + Tools: {tools} + Tool names: {tool_names} + + Question: {input} + {agent_scratchpad} + """) + + # for type AGENT + agent = create_react_agent(llm, tools, prompt) + agent_executor = AgentExecutor( + agent=agent, tools=tools, handle_parsing_errors=True, max_iterations=1 + ) + + try: + agent_executor.invoke({"input": "hello"}, {"callbacks": [handler]}) + except Exception: + pass + + try: + test_tool.invoke("simple input", {"callbacks": [handler]}) + except Exception: + pass + + from langchain_core.prompts import PromptTemplate as CorePromptTemplate + + # for type CHAIN + chain_prompt = CorePromptTemplate.from_template("Answer: {question}") + simple_chain = chain_prompt | llm + + try: + simple_chain.invoke({"question": "hi"}, {"callbacks": [handler]}) + except Exception: + pass + + # for type RETRIEVER + from langchain_core.retrievers import BaseRetriever + from langchain_core.documents import Document + + class SimpleRetriever(BaseRetriever): + def _get_relevant_documents(self, query: str, *, run_manager): + return [Document(page_content="test doc")] + + try: + SimpleRetriever().invoke("query", {"callbacks": [handler]}) + except Exception: + pass + + handler.client.flush() + trace = get_api().trace.get(trace_id) + + # Validate all expected observation types are created + types_found = {obs.type for obs in trace.observations} + expected_types = {"AGENT", "TOOL", "CHAIN", "RETRIEVER", "GENERATION"} + + for obs_type in expected_types: + obs_count = len([obs for obs in trace.observations if obs.type == obs_type]) + assert obs_count > 0, f"Expected {obs_type} observations, found {obs_count}" + + assert expected_types.issubset( + types_found + ), f"Missing types: {expected_types - types_found}" From 12b806f57b93e87418b9b0cdec9d7b4bc2e1154f Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 20 Aug 2025 11:07:38 +0200 Subject: [PATCH 50/66] add core test --- tests/test_core_sdk.py | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/test_core_sdk.py b/tests/test_core_sdk.py index 9d1acae85..950489cc4 100644 --- a/tests/test_core_sdk.py +++ b/tests/test_core_sdk.py @@ -1878,3 +1878,53 @@ def test_generate_trace_id(): project_id = langfuse._get_project_id() trace_url = langfuse.get_trace_url(trace_id=trace_id) assert trace_url == f"http://localhost:3000/project/{project_id}/traces/{trace_id}" + + +def test_start_as_current_observation_types(): + """Test creating different observation types using start_as_current_observation.""" + langfuse = Langfuse() + + observation_types = [ + "span", + "generation", + "agent", + "tool", + "chain", + "retriever", + "evaluator", + "embedding", + "guardrail", + ] + + with langfuse.start_as_current_span(name="parent") as parent_span: + parent_span.update_trace(name="observation-types-test") + trace_id = parent_span.trace_id + + for obs_type in observation_types: + with parent_span.start_as_current_observation( + name=f"test-{obs_type}", as_type=obs_type + ): + pass + + langfuse.flush() + + api = get_api() + trace = api.trace.get(trace_id) + + # Check we have all expected observation types + found_types = {obs.type for obs in trace.observations} + expected_types = {obs_type.upper() for obs_type in observation_types} | { + "SPAN" + } # includes parent span + assert expected_types.issubset( + found_types + ), f"Missing types: {expected_types - found_types}" + + # Verify each specific observation exists + for obs_type in observation_types: + observations = [ + obs + for obs in trace.observations + if obs.name == f"test-{obs_type}" and obs.type == obs_type.upper() + ] + assert len(observations) == 1, f"Expected one {obs_type.upper()} observation" From 1ce911fed79fe6f67026b6a1b2b787311cf6931b Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 20 Aug 2025 14:15:32 +0200 Subject: [PATCH 51/66] cleanup --- langfuse/_client/client.py | 89 ++++++++++++++++++++--------------- langfuse/_client/constants.py | 2 +- langfuse/_client/observe.py | 13 ++--- langfuse/_client/span.py | 28 ++++------- 4 files changed, 65 insertions(+), 67 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 97cbbca30..6b4a1d751 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -10,7 +10,18 @@ from datetime import datetime from hashlib import sha256 from time import time_ns -from typing import Any, Dict, List, Literal, Optional, Union, cast, overload +from typing import ( + Any, + Dict, + List, + Literal, + Optional, + Union, + Type, + cast, + overload, + get_args, +) import backoff import httpx @@ -39,6 +50,7 @@ from langfuse._client.constants import ( ObservationTypeLiteral, ObservationTypeLiteralNoEvent, + ObservationTypeGenerationLike, ) from langfuse._client.resource_manager import LangfuseResourceManager from langfuse._client.span import ( @@ -656,10 +668,14 @@ def _create_observation_from_otel_span( LangfuseGuardrail, ]: """Create the appropriate observation type from an OTEL span.""" - if as_type == "generation": - return LangfuseGeneration( + if as_type in get_args(ObservationTypeGenerationLike): + observation_class = self._get_span_class(as_type) + # Type ignore to prevent overloads of internal _get_span_class function, + # issue is that LangfuseEvent could be returned + return observation_class( # type: ignore[return-value] otel_span=otel_span, langfuse_client=self, + environment=self._environment, input=input, output=output, metadata=metadata, @@ -673,21 +689,12 @@ def _create_observation_from_otel_span( cost_details=cost_details, prompt=prompt, ) - elif as_type == "span": - return LangfuseSpan( - otel_span=otel_span, - langfuse_client=self, - environment=self._environment, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - ) else: - # For all other observation types (agent, tool, etc.), create a span and set the type - span = LangfuseSpan( + # For other types (e.g. span, guardrail), create appropriate class without generation properties + observation_class = self._get_span_class(as_type) + # Type ignore to prevent overloads of internal _get_span_class function, + # issue is that LangfuseEvent could be returned + return observation_class( # type: ignore[return-value] otel_span=otel_span, langfuse_client=self, environment=self._environment, @@ -698,10 +705,9 @@ def _create_observation_from_otel_span( level=level, status_message=status_message, ) - # Set the observation type on the span - span._observation_type = as_type - span._otel_span.set_attribute("langfuse.observation.type", as_type) - return span + # span._observation_type = as_type + # span._otel_span.set_attribute("langfuse.observation.type", as_type) + # return span def start_generation( self, @@ -1075,8 +1081,8 @@ def start_as_current_observation( status_message: Optional status message for the observation end_on_exit (default: True): Whether to end the span automatically when leaving the context manager. If False, the span must be manually ended to avoid memory leaks. - # TODO: also add the generation like types here! - The following parameters are only available when as_type="generation": + The following parameters are available when as_type is: "generation", "agent", + "tool", "chain", "retriever", "evaluator" or "embedding". completion_start_time: When the model started generating the response model: Name/identifier of the AI model used (e.g., "gpt-4") model_parameters: Parameters used for the model (e.g., temperature, max_tokens) @@ -1285,7 +1291,18 @@ def start_as_current_observation( def _get_span_class( self, as_type: ObservationTypeLiteral, - ) -> type: + ) -> Union[ + Type[LangfuseAgent], + Type[LangfuseTool], + Type[LangfuseChain], + Type[LangfuseRetriever], + Type[LangfuseEvaluator], + Type[LangfuseEmbedding], + Type[LangfuseGuardrail], + Type[LangfuseGeneration], + Type[LangfuseEvent], + Type[LangfuseSpan], + ]: """Get the appropriate span class based on as_type.""" normalized_type = as_type.lower() @@ -1400,7 +1417,15 @@ def _start_as_current_otel_span_with_processed_media( "status_message": status_message, } - if span_class == LangfuseGeneration: + if span_class in [ + LangfuseGeneration, + LangfuseAgent, + LangfuseTool, + LangfuseChain, + LangfuseRetriever, + LangfuseEvaluator, + LangfuseEmbedding, + ]: common_args.update( { "completion_start_time": completion_start_time, @@ -1411,19 +1436,7 @@ def _start_as_current_otel_span_with_processed_media( "prompt": prompt, } ) - # TODO: for some, create generation-like classes with those props. - elif span_class in [ - LangfuseSpan, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, - LangfuseEmbedding, - LangfuseGuardrail, - ]: - # set their type internally in the class - pass + # For span and guardrail types, no generation properties needed yield span_class(**common_args) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 12d307ffa..0f821b771 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -9,7 +9,7 @@ LANGFUSE_TRACER_NAME = "langfuse-sdk" -"""Note: this type is used with .__args__ in some cases and therefore must remain flat""" +"""Note: this type is used with .__args__ / get_args in some cases and therefore must remain flat""" ObservationTypeGenerationLike: TypeAlias = Literal[ "generation", "agent", diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 89758498e..3e7d5aedc 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -109,8 +109,9 @@ def observe( name (Optional[str]): Custom name for the created trace or span. If not provided, the function name is used. as_type (Optional[Literal]): Set the observation type. Supported values: "generation", "span", "agent", "tool", "chain", "retriever", "embedding", "evaluator", "guardrail". - When set to "generation", creates a specialized LLM generation span with model metrics support. - Other types create spans with the specified type for graph visualization and filtering in the Langfuse UI. + Observation types are highlighted in the Langfuse UI for filtering and visualization. + The types "generation", "agent", "tool", "chain", "retriever", "embedding", "evaluator" create a span which + allows to set additional attributes such as model metrics.. Returns: Callable: A wrapped version of the original function that automatically creates and manages Langfuse spans. @@ -136,13 +137,6 @@ async def generate_answer(query): return response.choices[0].message.content ``` - For automatic graph instrumentation with agent workflows: - ```python - @observe(as_type="agent") - def planning_agent(): - return create_plan() - ``` - For trace context propagation between functions: ```python @observe() @@ -369,7 +363,6 @@ def sync_wrapper(*args: Any, **kwargs: Any) -> Any: # Set public key in execution context for nested decorated functions with _set_current_public_key(public_key): langfuse_client = get_client(public_key=public_key) - context_manager: Optional[ Union[ _AgnosticContextManager[LangfuseGeneration], diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index cc4f5082d..9b341aae6 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -116,7 +116,6 @@ def __init__( LangfuseOtelSpanAttributes.OBSERVATION_TYPE, as_type ) self._langfuse_client = langfuse_client - self._observation_type = as_type self.trace_id = self._langfuse_client._get_otel_trace_id(otel_span) @@ -606,15 +605,7 @@ def update( level=level, status_message=status_message, observation_type=cast( - Literal[ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ], + ObservationTypeGenerationLike, self._observation_type, ), completion_start_time=completion_start_time, @@ -1072,7 +1063,8 @@ class LangfuseSpan(LangfuseObservationWrapper): This class represents a general-purpose span that can be used to trace any operation in your application. It extends the base LangfuseObservationWrapper with specific methods for creating child spans, generations, and updating - span-specific attributes. + span-specific attributes. If possible, use a more specific type for + better observability and insights. """ def __init__( @@ -1602,7 +1594,7 @@ def update( class LangfuseAgent(LangfuseObservationWrapper): - """Specialized span for agent observations in agentic workflows.""" + """Agent observation for reasoning blocks that act on tools using LLM guidance.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseAgent span.""" @@ -1611,7 +1603,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseTool(LangfuseObservationWrapper): - """Specialized span for tool observations in agentic workflows.""" + """Tool observation representing external tool calls, e.g., calling a weather API.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseTool span.""" @@ -1620,7 +1612,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseChain(LangfuseObservationWrapper): - """Specialized span for chain observations in agentic workflows.""" + """Chain observation for connecting LLM application steps, e.g. passing context from retriever to LLM.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseChain span.""" @@ -1629,7 +1621,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseRetriever(LangfuseObservationWrapper): - """Specialized span for retriever observations in agentic workflows.""" + """Retriever observation for data retrieval steps, e.g. vector store or database queries.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseRetriever span.""" @@ -1638,7 +1630,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseEmbedding(LangfuseObservationWrapper): - """Specialized span for embedding observations in agentic workflows.""" + """Embedding observation for LLM embedding calls, typically used before retrieval.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEmbedding span.""" @@ -1647,7 +1639,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseEvaluator(LangfuseObservationWrapper): - """Specialized span for evaluator observations in agentic workflows.""" + """Evaluator observation for assessing relevance, correctness, or helpfulness of LLM outputs.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseEvaluator span.""" @@ -1656,7 +1648,7 @@ def __init__(self, **kwargs: Any) -> None: class LangfuseGuardrail(LangfuseObservationWrapper): - """Specialized span for guardrail observations in agentic workflows.""" + """Guardrail observation for protection e.g. against jailbreaks or offensive content.""" def __init__(self, **kwargs: Any) -> None: """Initialize a new LangfuseGuardrail span.""" From d66d00381c150ac314678553b0ef28f5d2459a5a Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 20 Aug 2025 18:34:06 +0200 Subject: [PATCH 52/66] add deprecation warning --- langfuse/_client/client.py | 23 ++++++- langfuse/_client/span.py | 34 ++++++++++- tests/test_deprecation.py | 119 +++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 tests/test_deprecation.py diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 6b4a1d751..a7f476db8 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -5,6 +5,7 @@ import logging import os +import warnings import re import urllib.parse from datetime import datetime @@ -727,7 +728,10 @@ def start_generation( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, ) -> LangfuseGeneration: - """Create a new generation span for model generations. + """[DEPRECATED] Create a new generation span for model generations. + + DEPRECATED: This method is deprecated and will be removed in a future version. + Use start_observation(as_type='generation') instead. This method creates a specialized span for tracking model generations. It includes additional fields specific to model generations such as model name, @@ -777,6 +781,12 @@ def start_generation( generation.end() ``` """ + warnings.warn( + "start_generation is deprecated and will be removed in a future version. " + "Use start_observation(as_type='generation') instead.", + DeprecationWarning, + stacklevel=2, + ) return self.start_observation( trace_context=trace_context, name=name, @@ -814,7 +824,10 @@ def start_as_current_generation( prompt: Optional[PromptClient] = None, end_on_exit: Optional[bool] = None, ) -> _AgnosticContextManager[LangfuseGeneration]: - """Create a new generation span and set it as the current span in a context manager. + """[DEPRECATED] Create a new generation span and set it as the current span in a context manager. + + DEPRECATED: This method is deprecated and will be removed in a future version. + Use start_as_current_observation(as_type='generation') instead. This method creates a specialized span for model generations and sets it as the current span within a context manager. Use this method with a 'with' statement to @@ -862,6 +875,12 @@ def start_as_current_generation( ) ``` """ + warnings.warn( + "start_as_current_generation is deprecated and will be removed in a future version. " + "Use start_as_current_observation(as_type='generation') instead.", + DeprecationWarning, + stacklevel=2, + ) return self.start_as_current_observation( trace_context=trace_context, name=name, diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 9b341aae6..82032c86e 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -15,6 +15,7 @@ from datetime import datetime from time import time_ns +import warnings from typing import ( TYPE_CHECKING, Any, @@ -1176,7 +1177,10 @@ def start_as_current_span( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, ) -> _AgnosticContextManager["LangfuseSpan"]: - """Create a new child span and set it as the current span in a context manager. + """[DEPRECATED] Create a new child span and set it as the current span in a context manager. + + DEPRECATED: This method is deprecated and will be removed in a future version. + Use start_as_current_observation(as_type='span') instead. This method creates a new child span and sets it as the current span within a context manager. It should be used with a 'with' statement to automatically @@ -1210,6 +1214,12 @@ def start_as_current_span( parent_span.update(output=result) ``` """ + warnings.warn( + "start_as_current_span is deprecated and will be removed in a future version. " + "Use start_as_current_observation(as_type='span') instead.", + DeprecationWarning, + stacklevel=2, + ) return self.start_as_current_observation( name=name, as_type="span", @@ -1238,7 +1248,10 @@ def start_generation( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, ) -> "LangfuseGeneration": - """Create a new child generation span. + """[DEPRECATED] Create a new child generation span. + + DEPRECATED: This method is deprecated and will be removed in a future version. + Use start_observation(as_type='generation') instead. This method creates a new child generation span with this span as the parent. Generation spans are specialized for AI/LLM operations and include additional @@ -1295,6 +1308,12 @@ def start_generation( span.end() ``` """ + warnings.warn( + "start_generation is deprecated and will be removed in a future version. " + "Use start_observation(as_type='generation') instead.", + DeprecationWarning, + stacklevel=2, + ) return self.start_observation( name=name, as_type="generation", @@ -1329,7 +1348,10 @@ def start_as_current_generation( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, ) -> _AgnosticContextManager["LangfuseGeneration"]: - """Create a new child generation span and set it as the current span in a context manager. + """[DEPRECATED] Create a new child generation span and set it as the current span in a context manager. + + DEPRECATED: This method is deprecated and will be removed in a future version. + Use start_as_current_observation(as_type='generation') instead. This method creates a new child generation span and sets it as the current span within a context manager. Generation spans are specialized for AI/LLM operations @@ -1381,6 +1403,12 @@ def start_as_current_generation( span.update(output={"answer": response.text, "source": "gpt-4"}) ``` """ + warnings.warn( + "start_as_current_generation is deprecated and will be removed in a future version. " + "Use start_as_current_observation(as_type='generation') instead.", + DeprecationWarning, + stacklevel=2, + ) return cast( _AgnosticContextManager["LangfuseGeneration"], self.start_as_current_observation( diff --git a/tests/test_deprecation.py b/tests/test_deprecation.py new file mode 100644 index 000000000..9877f97d1 --- /dev/null +++ b/tests/test_deprecation.py @@ -0,0 +1,119 @@ +"""Tests for deprecation warnings on deprecated functions.""" + +import warnings +import pytest +from unittest.mock import patch + +from langfuse import Langfuse + + +class TestDeprecationWarnings: + """Test that deprecated functions emit proper deprecation warnings.""" + + # List of deprecated functions and their expected warning messages. Target is the object they are called on. + DEPRECATED_FUNCTIONS = [ + # on the client: + { + "method": "start_generation", + "target": "client", + "kwargs": {"name": "test_generation"}, + "expected_message": "start_generation is deprecated and will be removed in a future version. Use start_observation(as_type='generation') instead.", + }, + { + "method": "start_as_current_generation", + "target": "client", + "kwargs": {"name": "test_generation"}, + "expected_message": "start_as_current_generation is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='generation') instead.", + }, + # on the span: + { + "method": "start_generation", + "target": "span", + "kwargs": {"name": "test_generation"}, + "expected_message": "start_generation is deprecated and will be removed in a future version. Use start_observation(as_type='generation') instead.", + }, + { + "method": "start_as_current_generation", + "target": "span", + "kwargs": {"name": "test_generation"}, + "expected_message": "start_as_current_generation is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='generation') instead.", + }, + { + "method": "start_as_current_span", + "target": "span", + "kwargs": {"name": "test_span"}, + "expected_message": "start_as_current_span is deprecated and will be removed in a future version. Use start_as_current_observation(as_type='span') instead.", + }, + ] + + @pytest.fixture + def langfuse_client(self): + """Create a Langfuse client for testing.""" + with patch.dict( + "os.environ", + { + "LANGFUSE_PUBLIC_KEY": "test_key", + "LANGFUSE_SECRET_KEY": "test_secret", + "LANGFUSE_HOST": "http://localhost:3000", + }, + ): + return Langfuse() + + @pytest.mark.parametrize("func_info", DEPRECATED_FUNCTIONS) + def test_deprecated_function_warnings(self, langfuse_client, func_info): + """Test that deprecated functions emit proper deprecation warnings.""" + method_name = func_info["method"] + target = func_info["target"] + kwargs = func_info["kwargs"] + expected_message = func_info["expected_message"] + + with warnings.catch_warnings(record=True) as warning_list: + warnings.simplefilter("always") + + try: + if target == "client": + # Test deprecated methods on the client + method = getattr(langfuse_client, method_name) + if "current" in method_name: + # Context manager methods + with method(**kwargs) as obj: + if hasattr(obj, "end"): + obj.end() + else: + # Regular methods + obj = method(**kwargs) + if hasattr(obj, "end"): + obj.end() + + elif target == "span": + # Test deprecated methods on spans + span = langfuse_client.start_span(name="test_parent") + method = getattr(span, method_name) + if "current" in method_name: + # Context manager methods + with method(**kwargs) as obj: + if hasattr(obj, "end"): + obj.end() + else: + # Regular methods + obj = method(**kwargs) + if hasattr(obj, "end"): + obj.end() + span.end() + + except Exception: + pass + + # Check that a deprecation warning was emitted + deprecation_warnings = [ + w for w in warning_list if issubclass(w.category, DeprecationWarning) + ] + assert ( + len(deprecation_warnings) > 0 + ), f"No DeprecationWarning emitted for {target}.{method_name}" + + # Check that the warning message matches expected + warning_messages = [str(w.message) for w in deprecation_warnings] + assert ( + expected_message in warning_messages + ), f"Expected warning message not found for {target}.{method_name}. Got: {warning_messages}" From 2e0b7a8752187960e844941109b706c39c6800a1 Mon Sep 17 00:00:00 2001 From: Nimar Date: Wed, 20 Aug 2025 18:43:36 +0200 Subject: [PATCH 53/66] fix types --- langfuse/_client/client.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index a7f476db8..81ed62254 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -672,8 +672,8 @@ def _create_observation_from_otel_span( if as_type in get_args(ObservationTypeGenerationLike): observation_class = self._get_span_class(as_type) # Type ignore to prevent overloads of internal _get_span_class function, - # issue is that LangfuseEvent could be returned - return observation_class( # type: ignore[return-value] + # issue is that LangfuseEvent could be returned and that classes have diff. args + return observation_class( # type: ignore[return-value,call-arg] otel_span=otel_span, langfuse_client=self, environment=self._environment, @@ -694,8 +694,8 @@ def _create_observation_from_otel_span( # For other types (e.g. span, guardrail), create appropriate class without generation properties observation_class = self._get_span_class(as_type) # Type ignore to prevent overloads of internal _get_span_class function, - # issue is that LangfuseEvent could be returned - return observation_class( # type: ignore[return-value] + # issue is that LangfuseEvent could be returned and that classes have diff. args + return observation_class( # type: ignore[return-value,call-arg] otel_span=otel_span, langfuse_client=self, environment=self._environment, @@ -1457,7 +1457,7 @@ def _start_as_current_otel_span_with_processed_media( ) # For span and guardrail types, no generation properties needed - yield span_class(**common_args) + yield span_class(**common_args) # type: ignore[arg-type] def _get_current_otel_span(self) -> Optional[otel_trace_api.Span]: current_span = otel_trace_api.get_current_span() From 0f2c731af62a5ab0225f47fa0c8d17afa404dbbf Mon Sep 17 00:00:00 2001 From: Nimar Date: Thu, 21 Aug 2025 15:45:30 +0200 Subject: [PATCH 54/66] change generation like and span like --- langfuse/_client/attributes.py | 9 ++- langfuse/_client/constants.py | 12 +-- langfuse/_client/span.py | 144 +++++++++++++++++++++------------ 3 files changed, 105 insertions(+), 60 deletions(-) diff --git a/langfuse/_client/attributes.py b/langfuse/_client/attributes.py index d0ee06a44..5ae81000c 100644 --- a/langfuse/_client/attributes.py +++ b/langfuse/_client/attributes.py @@ -14,7 +14,10 @@ from datetime import datetime from typing import Any, Dict, List, Literal, Optional, Union -from langfuse._client.constants import ObservationTypeGenerationLike +from langfuse._client.constants import ( + ObservationTypeGenerationLike, + ObservationTypeSpanLike, +) from langfuse._utils.serializer import EventSerializer from langfuse.model import PromptClient @@ -95,7 +98,9 @@ def create_span_attributes( level: Optional[SpanLevel] = None, status_message: Optional[str] = None, version: Optional[str] = None, - observation_type: Optional[Literal["span", "guardrail", "event"]] = "span", + observation_type: Optional[ + Union[ObservationTypeSpanLike, Literal["event"]] + ] = "span", ) -> dict: attributes = { LangfuseOtelSpanAttributes.OBSERVATION_TYPE: observation_type, diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index 0f821b771..c60f3cec7 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -12,20 +12,22 @@ """Note: this type is used with .__args__ / get_args in some cases and therefore must remain flat""" ObservationTypeGenerationLike: TypeAlias = Literal[ "generation", + "embedding", +] + +ObservationTypeSpanLike: TypeAlias = Literal[ + "span", "agent", "tool", "chain", "retriever", "evaluator", - "embedding", + "guardrail", ] ObservationTypeLiteralNoEvent: TypeAlias = Union[ ObservationTypeGenerationLike, - Literal[ - "span", - "guardrail", - ], + ObservationTypeSpanLike, ] ObservationTypeLiteral: TypeAlias = Union[ diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 82032c86e..d1b2dc0e3 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -47,7 +47,9 @@ from langfuse._client.constants import ( ObservationTypeLiteral, ObservationTypeGenerationLike, + ObservationTypeSpanLike, ObservationTypeLiteralNoEvent, + get_observation_types_list, ) from langfuse.logger import langfuse_logger from langfuse.types import MapValue, ScoreDataType, SpanLevel @@ -142,7 +144,7 @@ def __init__( attributes = {} - if as_type in get_args(ObservationTypeGenerationLike): + if as_type in get_observation_types_list(ObservationTypeGenerationLike): attributes = create_generation_attributes( input=media_processed_input, output=media_processed_output, @@ -157,21 +159,13 @@ def __init__( cost_details=cost_details, prompt=prompt, observation_type=cast( - Literal[ - "generation", - "agent", - "tool", - "chain", - "retriever", - "evaluator", - "embedding", - ], + ObservationTypeGenerationLike, as_type, ), ) else: - # For span-like types: "span", "guardrail", "event" + # For span-like types and events attributes = create_span_attributes( input=media_processed_input, output=media_processed_output, @@ -180,8 +174,12 @@ def __init__( level=level, status_message=status_message, observation_type=cast( - Optional[Literal["span", "guardrail", "event"]], - as_type if as_type in ["span", "guardrail", "event"] else None, + Optional[Union[ObservationTypeSpanLike, Literal["event"]]], + as_type + if as_type + in get_observation_types_list(ObservationTypeSpanLike) + or as_type == "event" + else None, ), ) @@ -597,7 +595,9 @@ def update( if name: self._otel_span.update_name(name) - if self._observation_type in get_args(ObservationTypeGenerationLike): + if self._observation_type in get_observation_types_list( + ObservationTypeGenerationLike + ): attributes = create_generation_attributes( input=processed_input, output=processed_output, @@ -617,7 +617,7 @@ def update( prompt=prompt, ) else: - # For span-like types: "span", "guardrail", "event" + # For span-like types and events attributes = create_span_attributes( input=processed_input, output=processed_output, @@ -626,9 +626,11 @@ def update( level=level, status_message=status_message, observation_type=cast( - Optional[Literal["span", "guardrail", "event"]], + Optional[Union[ObservationTypeSpanLike, Literal["event"]]], self._observation_type - if self._observation_type in ["span", "guardrail", "event"] + if self._observation_type + in get_observation_types_list(ObservationTypeSpanLike) + or self._observation_type == "event" else None, ), ) @@ -683,12 +685,6 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, ) -> "LangfuseAgent": ... @overload @@ -703,12 +699,6 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, ) -> "LangfuseTool": ... @overload @@ -723,12 +713,6 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, ) -> "LangfuseChain": ... @overload @@ -743,12 +727,6 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, ) -> "LangfuseRetriever": ... @overload @@ -763,12 +741,6 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, - completion_start_time: Optional[datetime] = None, - model: Optional[str] = None, - model_parameters: Optional[Dict[str, MapValue]] = None, - usage_details: Optional[Dict[str, int]] = None, - cost_details: Optional[Dict[str, float]] = None, - prompt: Optional[PromptClient] = None, ) -> "LangfuseEvaluator": ... @overload @@ -912,7 +884,7 @@ def start_observation( "status_message": status_message, } - if as_type in get_args(ObservationTypeGenerationLike): + if as_type in get_observation_types_list(ObservationTypeGenerationLike): common_args.update( { "completion_start_time": completion_start_time, @@ -960,15 +932,81 @@ def start_as_current_observation( prompt: Optional[PromptClient] = None, ) -> _AgnosticContextManager[ Union[ - "LangfuseAgent", - "LangfuseTool", - "LangfuseChain", - "LangfuseRetriever", - "LangfuseEvaluator", + "LangfuseGeneration", "LangfuseEmbedding", ] ]: ... + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["agent"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseAgent"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["tool"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseTool"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["chain"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseChain"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["retriever"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseRetriever"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["evaluator"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + ) -> _AgnosticContextManager["LangfuseEvaluator"]: ... + @overload def start_as_current_observation( self, From b4fb6a6dce49a5b42e3b21ec7bc7304729f6f98c Mon Sep 17 00:00:00 2001 From: Nimar Date: Thu, 21 Aug 2025 15:58:20 +0200 Subject: [PATCH 55/66] fix --- langfuse/_client/client.py | 4 ++-- langfuse/_client/span.py | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 81ed62254..d283f8b26 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -21,7 +21,6 @@ Type, cast, overload, - get_args, ) import backoff @@ -52,6 +51,7 @@ ObservationTypeLiteral, ObservationTypeLiteralNoEvent, ObservationTypeGenerationLike, + get_observation_types_list, ) from langfuse._client.resource_manager import LangfuseResourceManager from langfuse._client.span import ( @@ -669,7 +669,7 @@ def _create_observation_from_otel_span( LangfuseGuardrail, ]: """Create the appropriate observation type from an OTEL span.""" - if as_type in get_args(ObservationTypeGenerationLike): + if as_type in get_observation_types_list(ObservationTypeGenerationLike): observation_class = self._get_span_class(as_type) # Type ignore to prevent overloads of internal _get_span_class function, # issue is that LangfuseEvent could be returned and that classes have diff. args diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index d1b2dc0e3..a38d99ad8 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -26,7 +26,6 @@ Type, Union, cast, - get_args, overload, ) From e7f34fe60fd6473667f3c973124e3ee207152040 Mon Sep 17 00:00:00 2001 From: Nimar Date: Thu, 21 Aug 2025 15:59:15 +0200 Subject: [PATCH 56/66] test format --- tests/test_core_sdk.py | 1 + tests/test_langchain.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_core_sdk.py b/tests/test_core_sdk.py index 950489cc4..dfb467a15 100644 --- a/tests/test_core_sdk.py +++ b/tests/test_core_sdk.py @@ -1907,6 +1907,7 @@ def test_start_as_current_observation_types(): pass langfuse.flush() + sleep(2) api = get_api() trace = api.trace.get(trace_id) diff --git a/tests/test_langchain.py b/tests/test_langchain.py index e869119dc..4e4093e38 100644 --- a/tests/test_langchain.py +++ b/tests/test_langchain.py @@ -1357,7 +1357,8 @@ def test_cached_token_usage(): def test_langchain_automatic_observation_types(): """Test that LangChain components automatically get correct observation types: - AGENT, TOOL, GENERATION, RETRIEVER, CHAIN""" + AGENT, TOOL, GENERATION, RETRIEVER, CHAIN + """ langfuse = Langfuse() with langfuse.start_as_current_span(name="observation_types_test_agent") as span: From 3aa4af8c53c28ffd903460c42f51a3d57f4d538a Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:04:55 +0200 Subject: [PATCH 57/66] from review --- langfuse/_client/client.py | 134 ++++++++++---------------- langfuse/_client/span.py | 7 +- langfuse/langchain/CallbackHandler.py | 21 +++- 3 files changed, 70 insertions(+), 92 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index d283f8b26..35c123456 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -51,6 +51,7 @@ ObservationTypeLiteral, ObservationTypeLiteralNoEvent, ObservationTypeGenerationLike, + ObservationTypeSpanLike, get_observation_types_list, ) from langfuse._client.resource_manager import LangfuseResourceManager @@ -1100,8 +1101,7 @@ def start_as_current_observation( status_message: Optional status message for the observation end_on_exit (default: True): Whether to end the span automatically when leaving the context manager. If False, the span must be manually ended to avoid memory leaks. - The following parameters are available when as_type is: "generation", "agent", - "tool", "chain", "retriever", "evaluator" or "embedding". + The following parameters are available when as_type is: "generation" or "embedding". completion_start_time: When the model started generating the response model: Name/identifier of the AI model used (e.g., "gpt-4") model_parameters: Parameters used for the model (e.g., temperature, max_tokens) @@ -1142,7 +1142,7 @@ def start_as_current_observation( generation.update(output=response) ``` """ - if as_type == "generation": + if as_type in get_observation_types_list(ObservationTypeGenerationLike): if trace_context: trace_id = trace_context.get("trace_id", None) parent_span_id = trace_context.get("parent_span_id", None) @@ -1153,9 +1153,12 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[LangfuseGeneration], + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseEmbedding], + ], self._create_span_with_parent_context( - as_type="generation", + as_type=as_type, name=name, remote_parent_span=remote_parent_span, parent=None, @@ -1176,9 +1179,12 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[LangfuseGeneration], + Union[ + _AgnosticContextManager[LangfuseGeneration], + _AgnosticContextManager[LangfuseEmbedding], + ], self._start_as_current_otel_span_with_processed_media( - as_type="generation", + as_type=as_type, name=name, end_on_exit=end_on_exit, input=input, @@ -1196,7 +1202,7 @@ def start_as_current_observation( ), ) - if as_type == "span": + if as_type in get_observation_types_list(ObservationTypeSpanLike): if trace_context: trace_id = trace_context.get("trace_id", None) parent_span_id = trace_context.get("parent_span_id", None) @@ -1207,9 +1213,17 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[LangfuseSpan], + Union[ + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseGuardrail], + ], self._create_span_with_parent_context( - as_type="span", + as_type=as_type, name=name, remote_parent_span=remote_parent_span, parent=None, @@ -1224,9 +1238,17 @@ def start_as_current_observation( ) return cast( - _AgnosticContextManager[LangfuseSpan], + Union[ + _AgnosticContextManager[LangfuseSpan], + _AgnosticContextManager[LangfuseAgent], + _AgnosticContextManager[LangfuseTool], + _AgnosticContextManager[LangfuseChain], + _AgnosticContextManager[LangfuseRetriever], + _AgnosticContextManager[LangfuseEvaluator], + _AgnosticContextManager[LangfuseGuardrail], + ], self._start_as_current_otel_span_with_processed_media( - as_type="span", + as_type=as_type, name=name, end_on_exit=end_on_exit, input=input, @@ -1238,73 +1260,20 @@ def start_as_current_observation( ), ) - if trace_context: - trace_id = trace_context.get("trace_id", None) - parent_span_id = trace_context.get("parent_span_id", None) - - if trace_id: - remote_parent_span = self._create_remote_parent_span( - trace_id=trace_id, parent_span_id=parent_span_id - ) - - return cast( - Union[ - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], - ], - self._create_span_with_parent_context( - as_type=as_type, - name=name, - remote_parent_span=remote_parent_span, - parent=None, - end_on_exit=end_on_exit, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), - ) - - return cast( - Union[ - _AgnosticContextManager[LangfuseAgent], - _AgnosticContextManager[LangfuseTool], - _AgnosticContextManager[LangfuseChain], - _AgnosticContextManager[LangfuseRetriever], - _AgnosticContextManager[LangfuseEvaluator], - _AgnosticContextManager[LangfuseEmbedding], - _AgnosticContextManager[LangfuseGuardrail], - ], - self._start_as_current_otel_span_with_processed_media( - as_type=as_type, - name=name, - end_on_exit=end_on_exit, - input=input, - output=output, - metadata=metadata, - version=version, - level=level, - status_message=status_message, - completion_start_time=completion_start_time, - model=model, - model_parameters=model_parameters, - usage_details=usage_details, - cost_details=cost_details, - prompt=prompt, - ), + # This should never be reached since all valid types are handled above + langfuse_logger.warning( + f"Unknown observation type: {as_type}, falling back to span" + ) + return self._start_as_current_otel_span_with_processed_media( + as_type="span", + name=name, + end_on_exit=end_on_exit, + input=input, + output=output, + metadata=metadata, + version=version, + level=level, + status_message=status_message, ) def _get_span_class( @@ -1438,11 +1407,6 @@ def _start_as_current_otel_span_with_processed_media( if span_class in [ LangfuseGeneration, - LangfuseAgent, - LangfuseTool, - LangfuseChain, - LangfuseRetriever, - LangfuseEvaluator, LangfuseEmbedding, ]: common_args.update( @@ -1455,7 +1419,7 @@ def _start_as_current_otel_span_with_processed_media( "prompt": prompt, } ) - # For span and guardrail types, no generation properties needed + # For span-like types (span, agent, tool, chain, retriever, evaluator, guardrail), no generation properties needed yield span_class(**common_args) # type: ignore[arg-type] diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index a38d99ad8..1e0d7196c 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -866,7 +866,10 @@ def start_observation( observation_class = _OBSERVATION_CLASS_MAP.get(as_type) if not observation_class: - raise ValueError(f"Unknown observation type: {as_type}") + langfuse_logger.warning( + f"Unknown observation type: {as_type}, falling back to LangfuseSpan" + ) + observation_class = LangfuseSpan with otel_trace_api.use_span(self._otel_span): new_otel_span = self._langfuse_client._otel_tracer.start_span(name=name) @@ -1644,7 +1647,7 @@ def update( cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, **kwargs: Any, - ) -> "LangfuseObservationWrapper": + ) -> "LangfuseEvent": """Update is not allowed for LangfuseEvent because events cannot be updated. This method logs a warning and returns self without making changes. diff --git a/langfuse/langchain/CallbackHandler.py b/langfuse/langchain/CallbackHandler.py index 717f31487..f45748b9e 100644 --- a/langfuse/langchain/CallbackHandler.py +++ b/langfuse/langchain/CallbackHandler.py @@ -3,6 +3,7 @@ import pydantic from langfuse._client.get_client import get_client +from langfuse._client.attributes import LangfuseOtelSpanAttributes from langfuse._client.span import ( LangfuseGeneration, LangfuseSpan, @@ -10,7 +11,6 @@ LangfuseChain, LangfuseTool, LangfuseRetriever, - LangfuseObservationWrapper, ) from langfuse.logger import langfuse_logger @@ -299,8 +299,7 @@ def on_chain_start( self.runs[run_id] = span else: self.runs[run_id] = cast( - # TODO: make this more precise (can be chain or agent here) - LangfuseObservationWrapper, + LangfuseChain, self.runs[parent_run_id], ).start_observation( name=span_name, @@ -365,7 +364,13 @@ def on_agent_action( if run_id not in self.runs: raise Exception("run not found") - self.runs[run_id].update( + agent_run = self.runs[run_id] + if hasattr(agent_run, '_otel_span'): + agent_run._otel_span.set_attribute( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "agent" + ) + + agent_run.update( output=action, input=kwargs.get("inputs"), ).end() @@ -388,7 +393,13 @@ def on_agent_finish( if run_id not in self.runs: raise Exception("run not found") - self.runs[run_id].update( + agent_run = self.runs[run_id] + if hasattr(agent_run, '_otel_span'): + agent_run._otel_span.set_attribute( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "agent" + ) + + agent_run.update( output=finish, input=kwargs.get("inputs"), ).end() From ddb767e76d108056957b6da4a96fce3ba605691a Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:05:15 +0200 Subject: [PATCH 58/66] format --- langfuse/langchain/CallbackHandler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/langfuse/langchain/CallbackHandler.py b/langfuse/langchain/CallbackHandler.py index f45748b9e..db90f10a0 100644 --- a/langfuse/langchain/CallbackHandler.py +++ b/langfuse/langchain/CallbackHandler.py @@ -365,7 +365,7 @@ def on_agent_action( raise Exception("run not found") agent_run = self.runs[run_id] - if hasattr(agent_run, '_otel_span'): + if hasattr(agent_run, "_otel_span"): agent_run._otel_span.set_attribute( LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "agent" ) @@ -394,7 +394,7 @@ def on_agent_finish( raise Exception("run not found") agent_run = self.runs[run_id] - if hasattr(agent_run, '_otel_span'): + if hasattr(agent_run, "_otel_span"): agent_run._otel_span.set_attribute( LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "agent" ) From 599ee51670ab94b87d1c0d0395d11fb0566f3085 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:08:03 +0200 Subject: [PATCH 59/66] add generation-like test --- tests/test_core_sdk.py | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/test_core_sdk.py b/tests/test_core_sdk.py index dfb467a15..d776ea9db 100644 --- a/tests/test_core_sdk.py +++ b/tests/test_core_sdk.py @@ -1929,3 +1929,91 @@ def test_start_as_current_observation_types(): if obs.name == f"test-{obs_type}" and obs.type == obs_type.upper() ] assert len(observations) == 1, f"Expected one {obs_type.upper()} observation" + + +def test_that_generation_like_properties_are_actually_created(): + """Test that generation-like observation types properly support generation properties.""" + from langfuse._client.constants import ( + get_observation_types_list, + ObservationTypeGenerationLike, + ) + + langfuse = Langfuse() + generation_like_types = get_observation_types_list(ObservationTypeGenerationLike) + + test_model = "test-model" + test_completion_start_time = datetime.now(timezone.utc) + test_model_parameters = {"temperature": 0.7, "max_tokens": 100} + test_usage_details = {"prompt_tokens": 10, "completion_tokens": 20} + test_cost_details = {"input": 0.01, "output": 0.02, "total": 0.03} + + with langfuse.start_as_current_span(name="parent") as parent_span: + parent_span.update_trace(name="generation-properties-test") + trace_id = parent_span.trace_id + + for obs_type in generation_like_types: + with parent_span.start_as_current_observation( + name=f"test-{obs_type}", + as_type=obs_type, + model=test_model, + completion_start_time=test_completion_start_time, + model_parameters=test_model_parameters, + usage_details=test_usage_details, + cost_details=test_cost_details, + ) as obs: + # Verify the properties are accessible on the observation object + if hasattr(obs, "model"): + assert ( + obs.model == test_model + ), f"{obs_type} should have model property" + if hasattr(obs, "completion_start_time"): + assert ( + obs.completion_start_time == test_completion_start_time + ), f"{obs_type} should have completion_start_time property" + if hasattr(obs, "model_parameters"): + assert ( + obs.model_parameters == test_model_parameters + ), f"{obs_type} should have model_parameters property" + if hasattr(obs, "usage_details"): + assert ( + obs.usage_details == test_usage_details + ), f"{obs_type} should have usage_details property" + if hasattr(obs, "cost_details"): + assert ( + obs.cost_details == test_cost_details + ), f"{obs_type} should have cost_details property" + + langfuse.flush() + + api = get_api() + trace = api.trace.get(trace_id) + + # Verify that the properties are persisted in the API for generation-like types + for obs_type in generation_like_types: + observations = [ + obs + for obs in trace.observations + if obs.name == f"test-{obs_type}" and obs.type == obs_type.upper() + ] + assert ( + len(observations) == 1 + ), f"Expected one {obs_type.upper()} observation, but found {len(observations)}" + + obs = observations[0] + + assert obs.model == test_model, f"{obs_type} should have model property" + assert ( + obs.model_parameters == test_model_parameters + ), f"{obs_type} should have model_parameters property" + + # usage_details + assert hasattr(obs, "usage_details"), f"{obs_type} should have usage_details" + assert obs.usage_details == dict( + test_usage_details, total=30 + ), f"{obs_type} should persist usage_details" # API adds total + + # completion_start_time + if obs.completion_start_time is not None: + assert ( + obs.completion_start_time is not None + ), f"{obs_type} should persist completion_start_time property" From fa5346cf254363dfe9f19afb20339504ca82b5c7 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:09:39 +0200 Subject: [PATCH 60/66] chore: update auto gen SDK (#1300) * unrelated changes to generated sdk * also readme * reset * revert * revert --- langfuse/_client/observe.py | 1 + langfuse/api/README.md | 28 +- langfuse/api/__init__.py | 18 + langfuse/api/client.py | 8 + langfuse/api/reference.md | 423 +++++++++++++++ langfuse/api/resources/__init__.py | 20 + .../resources/annotation_queues/__init__.py | 8 + .../api/resources/annotation_queues/client.py | 494 ++++++++++++++++++ .../annotation_queues/types/__init__.py | 12 + .../annotation_queue_assignment_request.py | 44 ++ ...te_annotation_queue_assignment_response.py | 46 ++ .../types/create_annotation_queue_request.py | 46 ++ ...te_annotation_queue_assignment_response.py | 42 ++ .../api/resources/commons/types/map_value.py | 1 - .../api/resources/llm_connections/__init__.py | 15 + .../api/resources/llm_connections/client.py | 340 ++++++++++++ .../llm_connections/types/__init__.py | 13 + .../llm_connections/types/llm_adapter.py | 37 ++ .../llm_connections/types/llm_connection.py | 85 +++ .../types/paginated_llm_connections.py | 45 ++ .../types/upsert_llm_connection_request.py | 88 ++++ 21 files changed, 1798 insertions(+), 16 deletions(-) create mode 100644 langfuse/api/resources/annotation_queues/types/annotation_queue_assignment_request.py create mode 100644 langfuse/api/resources/annotation_queues/types/create_annotation_queue_assignment_response.py create mode 100644 langfuse/api/resources/annotation_queues/types/create_annotation_queue_request.py create mode 100644 langfuse/api/resources/annotation_queues/types/delete_annotation_queue_assignment_response.py create mode 100644 langfuse/api/resources/llm_connections/__init__.py create mode 100644 langfuse/api/resources/llm_connections/client.py create mode 100644 langfuse/api/resources/llm_connections/types/__init__.py create mode 100644 langfuse/api/resources/llm_connections/types/llm_adapter.py create mode 100644 langfuse/api/resources/llm_connections/types/llm_connection.py create mode 100644 langfuse/api/resources/llm_connections/types/paginated_llm_connections.py create mode 100644 langfuse/api/resources/llm_connections/types/upsert_llm_connection_request.py diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 3e7d5aedc..06fe651c3 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -16,6 +16,7 @@ Union, cast, overload, + get_args, ) from opentelemetry.util._decorator import _AgnosticContextManager diff --git a/langfuse/api/README.md b/langfuse/api/README.md index feb6512ef..d7fa24a33 100644 --- a/langfuse/api/README.md +++ b/langfuse/api/README.md @@ -16,7 +16,7 @@ pip install langfuse Instantiate and use the client with the following: ```python -from langfuse import AnnotationQueueObjectType, CreateAnnotationQueueItemRequest +from langfuse import CreateAnnotationQueueRequest from langfuse.client import FernLangfuse client = FernLangfuse( @@ -27,11 +27,10 @@ client = FernLangfuse( password="YOUR_PASSWORD", base_url="https://yourhost.com/path/to/api", ) -client.annotation_queues.create_queue_item( - queue_id="queueId", - request=CreateAnnotationQueueItemRequest( - object_id="objectId", - object_type=AnnotationQueueObjectType.TRACE, +client.annotation_queues.create_queue( + request=CreateAnnotationQueueRequest( + name="name", + score_config_ids=["scoreConfigIds", "scoreConfigIds"], ), ) ``` @@ -43,7 +42,7 @@ The SDK also exports an `async` client so that you can make non-blocking calls t ```python import asyncio -from langfuse import AnnotationQueueObjectType, CreateAnnotationQueueItemRequest +from langfuse import CreateAnnotationQueueRequest from langfuse.client import AsyncFernLangfuse client = AsyncFernLangfuse( @@ -57,11 +56,10 @@ client = AsyncFernLangfuse( async def main() -> None: - await client.annotation_queues.create_queue_item( - queue_id="queueId", - request=CreateAnnotationQueueItemRequest( - object_id="objectId", - object_type=AnnotationQueueObjectType.TRACE, + await client.annotation_queues.create_queue( + request=CreateAnnotationQueueRequest( + name="name", + score_config_ids=["scoreConfigIds", "scoreConfigIds"], ), ) @@ -78,7 +76,7 @@ will be thrown. from .api_error import ApiError try: - client.annotation_queues.create_queue_item(...) + client.annotation_queues.create_queue(...) except ApiError as e: print(e.status_code) print(e.body) @@ -101,7 +99,7 @@ A request is deemed retriable when any of the following HTTP status codes is ret Use the `max_retries` request option to configure this behavior. ```python -client.annotation_queues.create_queue_item(...,{ +client.annotation_queues.create_queue(...,{ max_retries=1 }) ``` @@ -118,7 +116,7 @@ client = FernLangfuse(..., { timeout=20.0 }, ) # Override timeout for a specific method -client.annotation_queues.create_queue_item(...,{ +client.annotation_queues.create_queue(...,{ timeout_in_seconds=1 }) ``` diff --git a/langfuse/api/__init__.py b/langfuse/api/__init__.py index 2a274a811..4f43e45f1 100644 --- a/langfuse/api/__init__.py +++ b/langfuse/api/__init__.py @@ -3,6 +3,7 @@ from .resources import ( AccessDeniedError, AnnotationQueue, + AnnotationQueueAssignmentRequest, AnnotationQueueItem, AnnotationQueueObjectType, AnnotationQueueStatus, @@ -28,7 +29,9 @@ Comment, CommentObjectType, ConfigCategory, + CreateAnnotationQueueAssignmentResponse, CreateAnnotationQueueItemRequest, + CreateAnnotationQueueRequest, CreateChatPromptRequest, CreateCommentRequest, CreateCommentResponse, @@ -57,6 +60,7 @@ DatasetRunItem, DatasetRunWithItems, DatasetStatus, + DeleteAnnotationQueueAssignmentResponse, DeleteAnnotationQueueItemResponse, DeleteDatasetItemResponse, DeleteDatasetRunResponse, @@ -93,6 +97,8 @@ IngestionResponse, IngestionSuccess, IngestionUsage, + LlmAdapter, + LlmConnection, MapValue, MediaContentType, MembershipRequest, @@ -126,6 +132,7 @@ PaginatedDatasetRunItems, PaginatedDatasetRuns, PaginatedDatasets, + PaginatedLlmConnections, PaginatedModels, PaginatedSessions, PatchMediaBody, @@ -185,6 +192,7 @@ UpdateObservationEvent, UpdateSpanBody, UpdateSpanEvent, + UpsertLlmConnectionRequest, Usage, UsageDetails, UserMeta, @@ -196,6 +204,7 @@ datasets, health, ingestion, + llm_connections, media, metrics, models, @@ -216,6 +225,7 @@ __all__ = [ "AccessDeniedError", "AnnotationQueue", + "AnnotationQueueAssignmentRequest", "AnnotationQueueItem", "AnnotationQueueObjectType", "AnnotationQueueStatus", @@ -241,7 +251,9 @@ "Comment", "CommentObjectType", "ConfigCategory", + "CreateAnnotationQueueAssignmentResponse", "CreateAnnotationQueueItemRequest", + "CreateAnnotationQueueRequest", "CreateChatPromptRequest", "CreateCommentRequest", "CreateCommentResponse", @@ -270,6 +282,7 @@ "DatasetRunItem", "DatasetRunWithItems", "DatasetStatus", + "DeleteAnnotationQueueAssignmentResponse", "DeleteAnnotationQueueItemResponse", "DeleteDatasetItemResponse", "DeleteDatasetRunResponse", @@ -306,6 +319,8 @@ "IngestionResponse", "IngestionSuccess", "IngestionUsage", + "LlmAdapter", + "LlmConnection", "MapValue", "MediaContentType", "MembershipRequest", @@ -339,6 +354,7 @@ "PaginatedDatasetRunItems", "PaginatedDatasetRuns", "PaginatedDatasets", + "PaginatedLlmConnections", "PaginatedModels", "PaginatedSessions", "PatchMediaBody", @@ -398,6 +414,7 @@ "UpdateObservationEvent", "UpdateSpanBody", "UpdateSpanEvent", + "UpsertLlmConnectionRequest", "Usage", "UsageDetails", "UserMeta", @@ -409,6 +426,7 @@ "datasets", "health", "ingestion", + "llm_connections", "media", "metrics", "models", diff --git a/langfuse/api/client.py b/langfuse/api/client.py index 87b46c2f8..f18caba1c 100644 --- a/langfuse/api/client.py +++ b/langfuse/api/client.py @@ -18,6 +18,10 @@ from .resources.datasets.client import AsyncDatasetsClient, DatasetsClient from .resources.health.client import AsyncHealthClient, HealthClient from .resources.ingestion.client import AsyncIngestionClient, IngestionClient +from .resources.llm_connections.client import ( + AsyncLlmConnectionsClient, + LlmConnectionsClient, +) from .resources.media.client import AsyncMediaClient, MediaClient from .resources.metrics.client import AsyncMetricsClient, MetricsClient from .resources.models.client import AsyncModelsClient, ModelsClient @@ -120,6 +124,7 @@ def __init__( self.datasets = DatasetsClient(client_wrapper=self._client_wrapper) self.health = HealthClient(client_wrapper=self._client_wrapper) self.ingestion = IngestionClient(client_wrapper=self._client_wrapper) + self.llm_connections = LlmConnectionsClient(client_wrapper=self._client_wrapper) self.media = MediaClient(client_wrapper=self._client_wrapper) self.metrics = MetricsClient(client_wrapper=self._client_wrapper) self.models = ModelsClient(client_wrapper=self._client_wrapper) @@ -218,6 +223,9 @@ def __init__( self.datasets = AsyncDatasetsClient(client_wrapper=self._client_wrapper) self.health = AsyncHealthClient(client_wrapper=self._client_wrapper) self.ingestion = AsyncIngestionClient(client_wrapper=self._client_wrapper) + self.llm_connections = AsyncLlmConnectionsClient( + client_wrapper=self._client_wrapper + ) self.media = AsyncMediaClient(client_wrapper=self._client_wrapper) self.metrics = AsyncMetricsClient(client_wrapper=self._client_wrapper) self.models = AsyncModelsClient(client_wrapper=self._client_wrapper) diff --git a/langfuse/api/reference.md b/langfuse/api/reference.md index 29a7db88b..ce4c4ecd8 100644 --- a/langfuse/api/reference.md +++ b/langfuse/api/reference.md @@ -77,6 +77,85 @@ client.annotation_queues.list_queues() + + + + +
client.annotation_queues.create_queue(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create an annotation queue +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse import CreateAnnotationQueueRequest +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.annotation_queues.create_queue( + request=CreateAnnotationQueueRequest( + name="name", + score_config_ids=["scoreConfigIds", "scoreConfigIds"], + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CreateAnnotationQueueRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -601,6 +680,180 @@ client.annotation_queues.delete_queue_item( + + + + +
client.annotation_queues.create_queue_assignment(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create an assignment for a user to an annotation queue +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse import AnnotationQueueAssignmentRequest +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.annotation_queues.create_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**queue_id:** `str` — The unique identifier of the annotation queue + +
+
+ +
+
+ +**request:** `AnnotationQueueAssignmentRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.annotation_queues.delete_queue_assignment(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete an assignment for a user to an annotation queue +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse import AnnotationQueueAssignmentRequest +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.annotation_queues.delete_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**queue_id:** `str` — The unique identifier of the annotation queue + +
+
+ +
+
+ +**request:** `AnnotationQueueAssignmentRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -2047,6 +2300,168 @@ client.ingestion.batch( + + + + +## LlmConnections +
client.llm_connections.list(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get all LLM connections in a project +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.llm_connections.list() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**page:** `typing.Optional[int]` — page number, starts at 1 + +
+
+ +
+
+ +**limit:** `typing.Optional[int]` — limit of items per page + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.llm_connections.upsert(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create or update an LLM connection. The connection is upserted on provider. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from langfuse import LlmAdapter, UpsertLlmConnectionRequest +from langfuse.client import FernLangfuse + +client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", +) +client.llm_connections.upsert( + request=UpsertLlmConnectionRequest( + provider="provider", + adapter=LlmAdapter.ANTHROPIC, + secret_key="secretKey", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `UpsertLlmConnectionRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
@@ -2907,6 +3322,14 @@ client.observations.get_many()
+**level:** `typing.Optional[ObservationLevel]` — Optional filter for observations with a specific level (e.g. "DEBUG", "DEFAULT", "WARNING", "ERROR"). + +
+
+ +
+
+ **parent_observation_id:** `typing.Optional[str]`
diff --git a/langfuse/api/resources/__init__.py b/langfuse/api/resources/__init__.py index 453774283..062c933be 100644 --- a/langfuse/api/resources/__init__.py +++ b/langfuse/api/resources/__init__.py @@ -9,6 +9,7 @@ datasets, health, ingestion, + llm_connections, media, metrics, models, @@ -27,10 +28,14 @@ ) from .annotation_queues import ( AnnotationQueue, + AnnotationQueueAssignmentRequest, AnnotationQueueItem, AnnotationQueueObjectType, AnnotationQueueStatus, + CreateAnnotationQueueAssignmentResponse, CreateAnnotationQueueItemRequest, + CreateAnnotationQueueRequest, + DeleteAnnotationQueueAssignmentResponse, DeleteAnnotationQueueItemResponse, PaginatedAnnotationQueueItems, PaginatedAnnotationQueues, @@ -143,6 +148,12 @@ UpdateSpanEvent, UsageDetails, ) +from .llm_connections import ( + LlmAdapter, + LlmConnection, + PaginatedLlmConnections, + UpsertLlmConnectionRequest, +) from .media import ( GetMediaResponse, GetMediaUploadUrlRequest, @@ -228,6 +239,7 @@ __all__ = [ "AccessDeniedError", "AnnotationQueue", + "AnnotationQueueAssignmentRequest", "AnnotationQueueItem", "AnnotationQueueObjectType", "AnnotationQueueStatus", @@ -253,7 +265,9 @@ "Comment", "CommentObjectType", "ConfigCategory", + "CreateAnnotationQueueAssignmentResponse", "CreateAnnotationQueueItemRequest", + "CreateAnnotationQueueRequest", "CreateChatPromptRequest", "CreateCommentRequest", "CreateCommentResponse", @@ -282,6 +296,7 @@ "DatasetRunItem", "DatasetRunWithItems", "DatasetStatus", + "DeleteAnnotationQueueAssignmentResponse", "DeleteAnnotationQueueItemResponse", "DeleteDatasetItemResponse", "DeleteDatasetRunResponse", @@ -318,6 +333,8 @@ "IngestionResponse", "IngestionSuccess", "IngestionUsage", + "LlmAdapter", + "LlmConnection", "MapValue", "MediaContentType", "MembershipRequest", @@ -351,6 +368,7 @@ "PaginatedDatasetRunItems", "PaginatedDatasetRuns", "PaginatedDatasets", + "PaginatedLlmConnections", "PaginatedModels", "PaginatedSessions", "PatchMediaBody", @@ -410,6 +428,7 @@ "UpdateObservationEvent", "UpdateSpanBody", "UpdateSpanEvent", + "UpsertLlmConnectionRequest", "Usage", "UsageDetails", "UserMeta", @@ -421,6 +440,7 @@ "datasets", "health", "ingestion", + "llm_connections", "media", "metrics", "models", diff --git a/langfuse/api/resources/annotation_queues/__init__.py b/langfuse/api/resources/annotation_queues/__init__.py index 50f79e893..eed891727 100644 --- a/langfuse/api/resources/annotation_queues/__init__.py +++ b/langfuse/api/resources/annotation_queues/__init__.py @@ -2,10 +2,14 @@ from .types import ( AnnotationQueue, + AnnotationQueueAssignmentRequest, AnnotationQueueItem, AnnotationQueueObjectType, AnnotationQueueStatus, + CreateAnnotationQueueAssignmentResponse, CreateAnnotationQueueItemRequest, + CreateAnnotationQueueRequest, + DeleteAnnotationQueueAssignmentResponse, DeleteAnnotationQueueItemResponse, PaginatedAnnotationQueueItems, PaginatedAnnotationQueues, @@ -14,10 +18,14 @@ __all__ = [ "AnnotationQueue", + "AnnotationQueueAssignmentRequest", "AnnotationQueueItem", "AnnotationQueueObjectType", "AnnotationQueueStatus", + "CreateAnnotationQueueAssignmentResponse", "CreateAnnotationQueueItemRequest", + "CreateAnnotationQueueRequest", + "DeleteAnnotationQueueAssignmentResponse", "DeleteAnnotationQueueItemResponse", "PaginatedAnnotationQueueItems", "PaginatedAnnotationQueues", diff --git a/langfuse/api/resources/annotation_queues/client.py b/langfuse/api/resources/annotation_queues/client.py index bc1fd287f..97c7c2216 100644 --- a/langfuse/api/resources/annotation_queues/client.py +++ b/langfuse/api/resources/annotation_queues/client.py @@ -14,9 +14,17 @@ from ..commons.errors.not_found_error import NotFoundError from ..commons.errors.unauthorized_error import UnauthorizedError from .types.annotation_queue import AnnotationQueue +from .types.annotation_queue_assignment_request import AnnotationQueueAssignmentRequest from .types.annotation_queue_item import AnnotationQueueItem from .types.annotation_queue_status import AnnotationQueueStatus +from .types.create_annotation_queue_assignment_response import ( + CreateAnnotationQueueAssignmentResponse, +) from .types.create_annotation_queue_item_request import CreateAnnotationQueueItemRequest +from .types.create_annotation_queue_request import CreateAnnotationQueueRequest +from .types.delete_annotation_queue_assignment_response import ( + DeleteAnnotationQueueAssignmentResponse, +) from .types.delete_annotation_queue_item_response import ( DeleteAnnotationQueueItemResponse, ) @@ -105,6 +113,79 @@ def list_queues( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def create_queue( + self, + *, + request: CreateAnnotationQueueRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> AnnotationQueue: + """ + Create an annotation queue + + Parameters + ---------- + request : CreateAnnotationQueueRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AnnotationQueue + + Examples + -------- + from langfuse import CreateAnnotationQueueRequest + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.annotation_queues.create_queue( + request=CreateAnnotationQueueRequest( + name="name", + score_config_ids=["scoreConfigIds", "scoreConfigIds"], + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "api/public/annotation-queues", + method="POST", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(AnnotationQueue, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + def get_queue( self, queue_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AnnotationQueue: @@ -559,6 +640,164 @@ def delete_queue_item( raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + def create_queue_assignment( + self, + queue_id: str, + *, + request: AnnotationQueueAssignmentRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> CreateAnnotationQueueAssignmentResponse: + """ + Create an assignment for a user to an annotation queue + + Parameters + ---------- + queue_id : str + The unique identifier of the annotation queue + + request : AnnotationQueueAssignmentRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CreateAnnotationQueueAssignmentResponse + + Examples + -------- + from langfuse import AnnotationQueueAssignmentRequest + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.annotation_queues.create_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"api/public/annotation-queues/{jsonable_encoder(queue_id)}/assignments", + method="POST", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + CreateAnnotationQueueAssignmentResponse, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def delete_queue_assignment( + self, + queue_id: str, + *, + request: AnnotationQueueAssignmentRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeleteAnnotationQueueAssignmentResponse: + """ + Delete an assignment for a user to an annotation queue + + Parameters + ---------- + queue_id : str + The unique identifier of the annotation queue + + request : AnnotationQueueAssignmentRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeleteAnnotationQueueAssignmentResponse + + Examples + -------- + from langfuse import AnnotationQueueAssignmentRequest + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.annotation_queues.delete_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + f"api/public/annotation-queues/{jsonable_encoder(queue_id)}/assignments", + method="DELETE", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + DeleteAnnotationQueueAssignmentResponse, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + class AsyncAnnotationQueuesClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -645,6 +884,87 @@ async def main() -> None: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + async def create_queue( + self, + *, + request: CreateAnnotationQueueRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> AnnotationQueue: + """ + Create an annotation queue + + Parameters + ---------- + request : CreateAnnotationQueueRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AnnotationQueue + + Examples + -------- + import asyncio + + from langfuse import CreateAnnotationQueueRequest + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.annotation_queues.create_queue( + request=CreateAnnotationQueueRequest( + name="name", + score_config_ids=["scoreConfigIds", "scoreConfigIds"], + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "api/public/annotation-queues", + method="POST", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(AnnotationQueue, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + async def get_queue( self, queue_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AnnotationQueue: @@ -1146,3 +1466,177 @@ async def main() -> None: except JSONDecodeError: raise ApiError(status_code=_response.status_code, body=_response.text) raise ApiError(status_code=_response.status_code, body=_response_json) + + async def create_queue_assignment( + self, + queue_id: str, + *, + request: AnnotationQueueAssignmentRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> CreateAnnotationQueueAssignmentResponse: + """ + Create an assignment for a user to an annotation queue + + Parameters + ---------- + queue_id : str + The unique identifier of the annotation queue + + request : AnnotationQueueAssignmentRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CreateAnnotationQueueAssignmentResponse + + Examples + -------- + import asyncio + + from langfuse import AnnotationQueueAssignmentRequest + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.annotation_queues.create_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/public/annotation-queues/{jsonable_encoder(queue_id)}/assignments", + method="POST", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + CreateAnnotationQueueAssignmentResponse, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def delete_queue_assignment( + self, + queue_id: str, + *, + request: AnnotationQueueAssignmentRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> DeleteAnnotationQueueAssignmentResponse: + """ + Delete an assignment for a user to an annotation queue + + Parameters + ---------- + queue_id : str + The unique identifier of the annotation queue + + request : AnnotationQueueAssignmentRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeleteAnnotationQueueAssignmentResponse + + Examples + -------- + import asyncio + + from langfuse import AnnotationQueueAssignmentRequest + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.annotation_queues.delete_queue_assignment( + queue_id="queueId", + request=AnnotationQueueAssignmentRequest( + user_id="userId", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + f"api/public/annotation-queues/{jsonable_encoder(queue_id)}/assignments", + method="DELETE", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + DeleteAnnotationQueueAssignmentResponse, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/langfuse/api/resources/annotation_queues/types/__init__.py b/langfuse/api/resources/annotation_queues/types/__init__.py index 110b991cf..9f9ce37dd 100644 --- a/langfuse/api/resources/annotation_queues/types/__init__.py +++ b/langfuse/api/resources/annotation_queues/types/__init__.py @@ -1,10 +1,18 @@ # This file was auto-generated by Fern from our API Definition. from .annotation_queue import AnnotationQueue +from .annotation_queue_assignment_request import AnnotationQueueAssignmentRequest from .annotation_queue_item import AnnotationQueueItem from .annotation_queue_object_type import AnnotationQueueObjectType from .annotation_queue_status import AnnotationQueueStatus +from .create_annotation_queue_assignment_response import ( + CreateAnnotationQueueAssignmentResponse, +) from .create_annotation_queue_item_request import CreateAnnotationQueueItemRequest +from .create_annotation_queue_request import CreateAnnotationQueueRequest +from .delete_annotation_queue_assignment_response import ( + DeleteAnnotationQueueAssignmentResponse, +) from .delete_annotation_queue_item_response import DeleteAnnotationQueueItemResponse from .paginated_annotation_queue_items import PaginatedAnnotationQueueItems from .paginated_annotation_queues import PaginatedAnnotationQueues @@ -12,10 +20,14 @@ __all__ = [ "AnnotationQueue", + "AnnotationQueueAssignmentRequest", "AnnotationQueueItem", "AnnotationQueueObjectType", "AnnotationQueueStatus", + "CreateAnnotationQueueAssignmentResponse", "CreateAnnotationQueueItemRequest", + "CreateAnnotationQueueRequest", + "DeleteAnnotationQueueAssignmentResponse", "DeleteAnnotationQueueItemResponse", "PaginatedAnnotationQueueItems", "PaginatedAnnotationQueues", diff --git a/langfuse/api/resources/annotation_queues/types/annotation_queue_assignment_request.py b/langfuse/api/resources/annotation_queues/types/annotation_queue_assignment_request.py new file mode 100644 index 000000000..aa3980438 --- /dev/null +++ b/langfuse/api/resources/annotation_queues/types/annotation_queue_assignment_request.py @@ -0,0 +1,44 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 + + +class AnnotationQueueAssignmentRequest(pydantic_v1.BaseModel): + user_id: str = pydantic_v1.Field(alias="userId") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/annotation_queues/types/create_annotation_queue_assignment_response.py b/langfuse/api/resources/annotation_queues/types/create_annotation_queue_assignment_response.py new file mode 100644 index 000000000..ae6a46862 --- /dev/null +++ b/langfuse/api/resources/annotation_queues/types/create_annotation_queue_assignment_response.py @@ -0,0 +1,46 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 + + +class CreateAnnotationQueueAssignmentResponse(pydantic_v1.BaseModel): + user_id: str = pydantic_v1.Field(alias="userId") + queue_id: str = pydantic_v1.Field(alias="queueId") + project_id: str = pydantic_v1.Field(alias="projectId") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/annotation_queues/types/create_annotation_queue_request.py b/langfuse/api/resources/annotation_queues/types/create_annotation_queue_request.py new file mode 100644 index 000000000..7f793cea2 --- /dev/null +++ b/langfuse/api/resources/annotation_queues/types/create_annotation_queue_request.py @@ -0,0 +1,46 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 + + +class CreateAnnotationQueueRequest(pydantic_v1.BaseModel): + name: str + description: typing.Optional[str] = None + score_config_ids: typing.List[str] = pydantic_v1.Field(alias="scoreConfigIds") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/annotation_queues/types/delete_annotation_queue_assignment_response.py b/langfuse/api/resources/annotation_queues/types/delete_annotation_queue_assignment_response.py new file mode 100644 index 000000000..e348d546c --- /dev/null +++ b/langfuse/api/resources/annotation_queues/types/delete_annotation_queue_assignment_response.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 + + +class DeleteAnnotationQueueAssignmentResponse(pydantic_v1.BaseModel): + success: bool + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/commons/types/map_value.py b/langfuse/api/resources/commons/types/map_value.py index 46115a967..e1e771a9b 100644 --- a/langfuse/api/resources/commons/types/map_value.py +++ b/langfuse/api/resources/commons/types/map_value.py @@ -5,7 +5,6 @@ MapValue = typing.Union[ typing.Optional[str], typing.Optional[int], - typing.Optional[float], typing.Optional[bool], typing.Optional[typing.List[str]], ] diff --git a/langfuse/api/resources/llm_connections/__init__.py b/langfuse/api/resources/llm_connections/__init__.py new file mode 100644 index 000000000..3cf778f1b --- /dev/null +++ b/langfuse/api/resources/llm_connections/__init__.py @@ -0,0 +1,15 @@ +# This file was auto-generated by Fern from our API Definition. + +from .types import ( + LlmAdapter, + LlmConnection, + PaginatedLlmConnections, + UpsertLlmConnectionRequest, +) + +__all__ = [ + "LlmAdapter", + "LlmConnection", + "PaginatedLlmConnections", + "UpsertLlmConnectionRequest", +] diff --git a/langfuse/api/resources/llm_connections/client.py b/langfuse/api/resources/llm_connections/client.py new file mode 100644 index 000000000..4497598c5 --- /dev/null +++ b/langfuse/api/resources/llm_connections/client.py @@ -0,0 +1,340 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.pydantic_utilities import pydantic_v1 +from ...core.request_options import RequestOptions +from ..commons.errors.access_denied_error import AccessDeniedError +from ..commons.errors.error import Error +from ..commons.errors.method_not_allowed_error import MethodNotAllowedError +from ..commons.errors.not_found_error import NotFoundError +from ..commons.errors.unauthorized_error import UnauthorizedError +from .types.llm_connection import LlmConnection +from .types.paginated_llm_connections import PaginatedLlmConnections +from .types.upsert_llm_connection_request import UpsertLlmConnectionRequest + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class LlmConnectionsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> PaginatedLlmConnections: + """ + Get all LLM connections in a project + + Parameters + ---------- + page : typing.Optional[int] + page number, starts at 1 + + limit : typing.Optional[int] + limit of items per page + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + PaginatedLlmConnections + + Examples + -------- + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.llm_connections.list() + """ + _response = self._client_wrapper.httpx_client.request( + "api/public/llm-connections", + method="GET", + params={"page": page, "limit": limit}, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + PaginatedLlmConnections, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + def upsert( + self, + *, + request: UpsertLlmConnectionRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> LlmConnection: + """ + Create or update an LLM connection. The connection is upserted on provider. + + Parameters + ---------- + request : UpsertLlmConnectionRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + LlmConnection + + Examples + -------- + from langfuse import LlmAdapter, UpsertLlmConnectionRequest + from langfuse.client import FernLangfuse + + client = FernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + client.llm_connections.upsert( + request=UpsertLlmConnectionRequest( + provider="provider", + adapter=LlmAdapter.ANTHROPIC, + secret_key="secretKey", + ), + ) + """ + _response = self._client_wrapper.httpx_client.request( + "api/public/llm-connections", + method="PUT", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(LlmConnection, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + +class AsyncLlmConnectionsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list( + self, + *, + page: typing.Optional[int] = None, + limit: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> PaginatedLlmConnections: + """ + Get all LLM connections in a project + + Parameters + ---------- + page : typing.Optional[int] + page number, starts at 1 + + limit : typing.Optional[int] + limit of items per page + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + PaginatedLlmConnections + + Examples + -------- + import asyncio + + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.llm_connections.list() + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "api/public/llm-connections", + method="GET", + params={"page": page, "limit": limit}, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as( + PaginatedLlmConnections, _response.json() + ) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) + + async def upsert( + self, + *, + request: UpsertLlmConnectionRequest, + request_options: typing.Optional[RequestOptions] = None, + ) -> LlmConnection: + """ + Create or update an LLM connection. The connection is upserted on provider. + + Parameters + ---------- + request : UpsertLlmConnectionRequest + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + LlmConnection + + Examples + -------- + import asyncio + + from langfuse import LlmAdapter, UpsertLlmConnectionRequest + from langfuse.client import AsyncFernLangfuse + + client = AsyncFernLangfuse( + x_langfuse_sdk_name="YOUR_X_LANGFUSE_SDK_NAME", + x_langfuse_sdk_version="YOUR_X_LANGFUSE_SDK_VERSION", + x_langfuse_public_key="YOUR_X_LANGFUSE_PUBLIC_KEY", + username="YOUR_USERNAME", + password="YOUR_PASSWORD", + base_url="https://yourhost.com/path/to/api", + ) + + + async def main() -> None: + await client.llm_connections.upsert( + request=UpsertLlmConnectionRequest( + provider="provider", + adapter=LlmAdapter.ANTHROPIC, + secret_key="secretKey", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._client_wrapper.httpx_client.request( + "api/public/llm-connections", + method="PUT", + json=request, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + return pydantic_v1.parse_obj_as(LlmConnection, _response.json()) # type: ignore + if _response.status_code == 400: + raise Error(pydantic_v1.parse_obj_as(typing.Any, _response.json())) # type: ignore + if _response.status_code == 401: + raise UnauthorizedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 403: + raise AccessDeniedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 405: + raise MethodNotAllowedError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + pydantic_v1.parse_obj_as(typing.Any, _response.json()) + ) # type: ignore + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, body=_response.text) + raise ApiError(status_code=_response.status_code, body=_response_json) diff --git a/langfuse/api/resources/llm_connections/types/__init__.py b/langfuse/api/resources/llm_connections/types/__init__.py new file mode 100644 index 000000000..b490e6e27 --- /dev/null +++ b/langfuse/api/resources/llm_connections/types/__init__.py @@ -0,0 +1,13 @@ +# This file was auto-generated by Fern from our API Definition. + +from .llm_adapter import LlmAdapter +from .llm_connection import LlmConnection +from .paginated_llm_connections import PaginatedLlmConnections +from .upsert_llm_connection_request import UpsertLlmConnectionRequest + +__all__ = [ + "LlmAdapter", + "LlmConnection", + "PaginatedLlmConnections", + "UpsertLlmConnectionRequest", +] diff --git a/langfuse/api/resources/llm_connections/types/llm_adapter.py b/langfuse/api/resources/llm_connections/types/llm_adapter.py new file mode 100644 index 000000000..d03513aeb --- /dev/null +++ b/langfuse/api/resources/llm_connections/types/llm_adapter.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import enum +import typing + +T_Result = typing.TypeVar("T_Result") + + +class LlmAdapter(str, enum.Enum): + ANTHROPIC = "anthropic" + OPEN_AI = "openai" + AZURE = "azure" + BEDROCK = "bedrock" + GOOGLE_VERTEX_AI = "google-vertex-ai" + GOOGLE_AI_STUDIO = "google-ai-studio" + + def visit( + self, + anthropic: typing.Callable[[], T_Result], + open_ai: typing.Callable[[], T_Result], + azure: typing.Callable[[], T_Result], + bedrock: typing.Callable[[], T_Result], + google_vertex_ai: typing.Callable[[], T_Result], + google_ai_studio: typing.Callable[[], T_Result], + ) -> T_Result: + if self is LlmAdapter.ANTHROPIC: + return anthropic() + if self is LlmAdapter.OPEN_AI: + return open_ai() + if self is LlmAdapter.AZURE: + return azure() + if self is LlmAdapter.BEDROCK: + return bedrock() + if self is LlmAdapter.GOOGLE_VERTEX_AI: + return google_vertex_ai() + if self is LlmAdapter.GOOGLE_AI_STUDIO: + return google_ai_studio() diff --git a/langfuse/api/resources/llm_connections/types/llm_connection.py b/langfuse/api/resources/llm_connections/types/llm_connection.py new file mode 100644 index 000000000..0b17b97a7 --- /dev/null +++ b/langfuse/api/resources/llm_connections/types/llm_connection.py @@ -0,0 +1,85 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 + + +class LlmConnection(pydantic_v1.BaseModel): + """ + LLM API connection configuration (secrets excluded) + """ + + id: str + provider: str = pydantic_v1.Field() + """ + Provider name (e.g., 'openai', 'my-gateway'). Must be unique in project, used for upserting. + """ + + adapter: str = pydantic_v1.Field() + """ + The adapter used to interface with the LLM + """ + + display_secret_key: str = pydantic_v1.Field(alias="displaySecretKey") + """ + Masked version of the secret key for display purposes + """ + + base_url: typing.Optional[str] = pydantic_v1.Field(alias="baseURL", default=None) + """ + Custom base URL for the LLM API + """ + + custom_models: typing.List[str] = pydantic_v1.Field(alias="customModels") + """ + List of custom model names available for this connection + """ + + with_default_models: bool = pydantic_v1.Field(alias="withDefaultModels") + """ + Whether to include default models for this adapter + """ + + extra_header_keys: typing.List[str] = pydantic_v1.Field(alias="extraHeaderKeys") + """ + Keys of extra headers sent with requests (values excluded for security) + """ + + created_at: dt.datetime = pydantic_v1.Field(alias="createdAt") + updated_at: dt.datetime = pydantic_v1.Field(alias="updatedAt") + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/llm_connections/types/paginated_llm_connections.py b/langfuse/api/resources/llm_connections/types/paginated_llm_connections.py new file mode 100644 index 000000000..986dbb0bb --- /dev/null +++ b/langfuse/api/resources/llm_connections/types/paginated_llm_connections.py @@ -0,0 +1,45 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 +from ...utils.resources.pagination.types.meta_response import MetaResponse +from .llm_connection import LlmConnection + + +class PaginatedLlmConnections(pydantic_v1.BaseModel): + data: typing.List[LlmConnection] + meta: MetaResponse + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} diff --git a/langfuse/api/resources/llm_connections/types/upsert_llm_connection_request.py b/langfuse/api/resources/llm_connections/types/upsert_llm_connection_request.py new file mode 100644 index 000000000..d0a5a368d --- /dev/null +++ b/langfuse/api/resources/llm_connections/types/upsert_llm_connection_request.py @@ -0,0 +1,88 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +from ....core.datetime_utils import serialize_datetime +from ....core.pydantic_utilities import deep_union_pydantic_dicts, pydantic_v1 +from .llm_adapter import LlmAdapter + + +class UpsertLlmConnectionRequest(pydantic_v1.BaseModel): + """ + Request to create or update an LLM connection (upsert) + """ + + provider: str = pydantic_v1.Field() + """ + Provider name (e.g., 'openai', 'my-gateway'). Must be unique in project, used for upserting. + """ + + adapter: LlmAdapter = pydantic_v1.Field() + """ + The adapter used to interface with the LLM + """ + + secret_key: str = pydantic_v1.Field(alias="secretKey") + """ + Secret key for the LLM API. + """ + + base_url: typing.Optional[str] = pydantic_v1.Field(alias="baseURL", default=None) + """ + Custom base URL for the LLM API + """ + + custom_models: typing.Optional[typing.List[str]] = pydantic_v1.Field( + alias="customModels", default=None + ) + """ + List of custom model names + """ + + with_default_models: typing.Optional[bool] = pydantic_v1.Field( + alias="withDefaultModels", default=None + ) + """ + Whether to include default models. Default is true. + """ + + extra_headers: typing.Optional[typing.Dict[str, str]] = pydantic_v1.Field( + alias="extraHeaders", default=None + ) + """ + Extra headers to send with requests + """ + + def json(self, **kwargs: typing.Any) -> str: + kwargs_with_defaults: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + return super().json(**kwargs_with_defaults) + + def dict(self, **kwargs: typing.Any) -> typing.Dict[str, typing.Any]: + kwargs_with_defaults_exclude_unset: typing.Any = { + "by_alias": True, + "exclude_unset": True, + **kwargs, + } + kwargs_with_defaults_exclude_none: typing.Any = { + "by_alias": True, + "exclude_none": True, + **kwargs, + } + + return deep_union_pydantic_dicts( + super().dict(**kwargs_with_defaults_exclude_unset), + super().dict(**kwargs_with_defaults_exclude_none), + ) + + class Config: + frozen = True + smart_union = True + allow_population_by_field_name = True + populate_by_name = True + extra = pydantic_v1.Extra.allow + json_encoders = {dt.datetime: serialize_datetime} From bb4cfabb44383d8ef098392d07b88e56d7c61c74 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:15:12 +0200 Subject: [PATCH 61/66] fix lint --- langfuse/_client/observe.py | 1 - 1 file changed, 1 deletion(-) diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 06fe651c3..3e7d5aedc 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -16,7 +16,6 @@ Union, cast, overload, - get_args, ) from opentelemetry.util._decorator import _AgnosticContextManager From 6da68c94a423df23a738f321e29f52284950c759 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 11:56:52 +0200 Subject: [PATCH 62/66] fix tests --- langfuse/_client/constants.py | 6 +++--- langfuse/_client/observe.py | 4 ++-- tests/test_core_sdk.py | 16 ++++++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/langfuse/_client/constants.py b/langfuse/_client/constants.py index c60f3cec7..b699480c0 100644 --- a/langfuse/_client/constants.py +++ b/langfuse/_client/constants.py @@ -30,14 +30,14 @@ ObservationTypeSpanLike, ] -ObservationTypeLiteral: TypeAlias = Union[ - ObservationTypeLiteralNoEvent, Literal["event"] -] """Enumeration of valid observation types for Langfuse tracing. This Literal defines all available observation types that can be used with the @observe decorator and other Langfuse SDK methods. """ +ObservationTypeLiteral: TypeAlias = Union[ + ObservationTypeLiteralNoEvent, Literal["event"] +] def get_observation_types_list( diff --git a/langfuse/_client/observe.py b/langfuse/_client/observe.py index 3e7d5aedc..ce848e04a 100644 --- a/langfuse/_client/observe.py +++ b/langfuse/_client/observe.py @@ -110,8 +110,8 @@ def observe( as_type (Optional[Literal]): Set the observation type. Supported values: "generation", "span", "agent", "tool", "chain", "retriever", "embedding", "evaluator", "guardrail". Observation types are highlighted in the Langfuse UI for filtering and visualization. - The types "generation", "agent", "tool", "chain", "retriever", "embedding", "evaluator" create a span which - allows to set additional attributes such as model metrics.. + The types "generation" and "embedding" create a span on which additional attributes such as model metrics + can be set. Returns: Callable: A wrapped version of the original function that automatically creates and manages Langfuse spans. diff --git a/tests/test_core_sdk.py b/tests/test_core_sdk.py index d776ea9db..507e66f32 100644 --- a/tests/test_core_sdk.py +++ b/tests/test_core_sdk.py @@ -1931,6 +1931,7 @@ def test_start_as_current_observation_types(): assert len(observations) == 1, f"Expected one {obs_type.upper()} observation" +@pytest.mark.skip(reason="Works after OSS release 3.102") def test_that_generation_like_properties_are_actually_created(): """Test that generation-like observation types properly support generation properties.""" from langfuse._client.constants import ( @@ -1943,7 +1944,7 @@ def test_that_generation_like_properties_are_actually_created(): test_model = "test-model" test_completion_start_time = datetime.now(timezone.utc) - test_model_parameters = {"temperature": 0.7, "max_tokens": 100} + test_model_parameters = {"temperature": "0.7", "max_tokens": "100"} test_usage_details = {"prompt_tokens": 10, "completion_tokens": 20} test_cost_details = {"input": 0.01, "output": 0.02, "total": 0.03} @@ -2012,8 +2013,11 @@ def test_that_generation_like_properties_are_actually_created(): test_usage_details, total=30 ), f"{obs_type} should persist usage_details" # API adds total - # completion_start_time - if obs.completion_start_time is not None: - assert ( - obs.completion_start_time is not None - ), f"{obs_type} should persist completion_start_time property" + assert ( + obs.cost_details == test_cost_details + ), f"{obs_type} should persist cost_details" + + # completion_start_time, because of time skew not asserting time + assert ( + obs.completion_start_time is not None + ), f"{obs_type} should persist completion_start_time property" From 34298e8462cc057df44c2852101678eab496793e Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 13:00:12 +0200 Subject: [PATCH 63/66] embedding correct attrs --- langfuse/_client/client.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 35c123456..7db635348 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -519,6 +519,12 @@ def start_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, ) -> LangfuseEmbedding: ... @overload @@ -1032,6 +1038,12 @@ def start_as_current_observation( version: Optional[str] = None, level: Optional[SpanLevel] = None, status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, end_on_exit: Optional[bool] = None, ) -> _AgnosticContextManager[LangfuseEmbedding]: ... From cc7820b6274a439c5988d4c44c07d034dda81c26 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 13:26:06 +0200 Subject: [PATCH 64/66] fix typing --- langfuse/_client/span.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index 1e0d7196c..c5e51b336 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -182,6 +182,7 @@ def __init__( ), ) + # We don't want to overwrite the observation type, and already set it attributes.pop(LangfuseOtelSpanAttributes.OBSERVATION_TYPE, None) self._otel_span.set_attributes( @@ -919,7 +920,7 @@ def start_as_current_observation( self, *, name: str, - as_type: ObservationTypeGenerationLike, + as_type: Literal["generation"], input: Optional[Any] = None, output: Optional[Any] = None, metadata: Optional[Any] = None, @@ -932,12 +933,27 @@ def start_as_current_observation( usage_details: Optional[Dict[str, int]] = None, cost_details: Optional[Dict[str, float]] = None, prompt: Optional[PromptClient] = None, - ) -> _AgnosticContextManager[ - Union[ - "LangfuseGeneration", - "LangfuseEmbedding", - ] - ]: ... + ) -> _AgnosticContextManager["LangfuseGeneration"]: ... + + @overload + def start_as_current_observation( + self, + *, + name: str, + as_type: Literal["embedding"], + input: Optional[Any] = None, + output: Optional[Any] = None, + metadata: Optional[Any] = None, + version: Optional[str] = None, + level: Optional[SpanLevel] = None, + status_message: Optional[str] = None, + completion_start_time: Optional[datetime] = None, + model: Optional[str] = None, + model_parameters: Optional[Dict[str, MapValue]] = None, + usage_details: Optional[Dict[str, int]] = None, + cost_details: Optional[Dict[str, float]] = None, + prompt: Optional[PromptClient] = None, + ) -> _AgnosticContextManager["LangfuseEmbedding"]: ... @overload def start_as_current_observation( From 9f3349ff61d7b2d13c5718fe2ab4a539531888c2 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 13:58:14 +0200 Subject: [PATCH 65/66] fix bug --- langfuse/_client/client.py | 7 ++++++- tests/test_core_sdk.py | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 7db635348..42fdf0354 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -1660,7 +1660,12 @@ def update_current_trace( current_otel_span = self._get_current_otel_span() if current_otel_span is not None: - span = LangfuseSpan( + existing_observation_type = current_otel_span.attributes.get( + LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "span" + ) + # We need to preserve the class to keep the corret observation type + span_class = self._get_span_class(existing_observation_type) + span = span_class( otel_span=current_otel_span, langfuse_client=self, environment=self._environment, diff --git a/tests/test_core_sdk.py b/tests/test_core_sdk.py index 507e66f32..9a758e38a 100644 --- a/tests/test_core_sdk.py +++ b/tests/test_core_sdk.py @@ -1931,7 +1931,6 @@ def test_start_as_current_observation_types(): assert len(observations) == 1, f"Expected one {obs_type.upper()} observation" -@pytest.mark.skip(reason="Works after OSS release 3.102") def test_that_generation_like_properties_are_actually_created(): """Test that generation-like observation types properly support generation properties.""" from langfuse._client.constants import ( From 9512f06a94c02a5c990c5c7fe0687ee0c4d68886 Mon Sep 17 00:00:00 2001 From: Nimar Date: Fri, 22 Aug 2025 14:07:27 +0200 Subject: [PATCH 66/66] fix mypy --- langfuse/_client/client.py | 2 +- langfuse/_client/span.py | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/langfuse/_client/client.py b/langfuse/_client/client.py index 42fdf0354..18eca4bfd 100644 --- a/langfuse/_client/client.py +++ b/langfuse/_client/client.py @@ -1660,7 +1660,7 @@ def update_current_trace( current_otel_span = self._get_current_otel_span() if current_otel_span is not None: - existing_observation_type = current_otel_span.attributes.get( + existing_observation_type = current_otel_span.attributes.get( # type: ignore[attr-defined] LangfuseOtelSpanAttributes.OBSERVATION_TYPE, "span" ) # We need to preserve the class to keep the corret observation type diff --git a/langfuse/_client/span.py b/langfuse/_client/span.py index c5e51b336..003c58706 100644 --- a/langfuse/_client/span.py +++ b/langfuse/_client/span.py @@ -1465,11 +1465,9 @@ def start_as_current_generation( DeprecationWarning, stacklevel=2, ) - return cast( - _AgnosticContextManager["LangfuseGeneration"], - self.start_as_current_observation( - name=name, - as_type="generation", + return self.start_as_current_observation( + name=name, + as_type="generation", input=input, output=output, metadata=metadata, @@ -1482,8 +1480,7 @@ def start_as_current_generation( usage_details=usage_details, cost_details=cost_details, prompt=prompt, - ), - ) + ) def create_event( self,