From 516d9a7c4ab2ede0260e17a6aeccb83b1177216c Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 10 Jan 2025 15:28:33 -0800 Subject: [PATCH 01/18] update prompt target name after arch_fc has identified tool --- crates/prompt_gateway/src/stream_context.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/prompt_gateway/src/stream_context.rs b/crates/prompt_gateway/src/stream_context.rs index b8a5007f..9782698e 100644 --- a/crates/prompt_gateway/src/stream_context.rs +++ b/crates/prompt_gateway/src/stream_context.rs @@ -263,6 +263,10 @@ impl StreamContext { ); } + // update prompt target name from the tool call + callout_context.prompt_target_name = + Some(self.tool_calls.as_ref().unwrap()[0].function.name.clone()); + self.schedule_api_call_request(callout_context); } @@ -359,8 +363,8 @@ impl StreamContext { let http_status = self .get_http_call_response_header(":status") .unwrap_or(StatusCode::OK.as_str().to_string()); - debug!("api_call_response_handler: http_status: {}", http_status); - if http_status != StatusCode::OK.as_str() { + debug!("api_call_response_handler: http_status: {}", http_status); + if http_status != StatusCode::OK.as_str() { warn!( "api server responded with non 2xx status code: {}", http_status From ebda682b309252603f91d341bdc1d248e8a980ce Mon Sep 17 00:00:00 2001 From: Salman Paracha Date: Fri, 10 Jan 2025 16:38:48 -0800 Subject: [PATCH 02/18] updated docs for 0.1.8 support (#366) * updated docs for 0.1.8 support * updated REAMDE on root * updated version reference to 0.1.8 in other parts of the repo --------- Co-authored-by: Salman Paracha --- README.md | 9 +- arch/tools/README.md | 2 +- .../img/arch_network_diagram_high_level.png | Bin 0 -> 155491 bytes docs/source/conf.py | 4 +- docs/source/get_started/intro_to_arch.rst | 5 +- docs/source/get_started/overview.rst | 6 ++ docs/source/get_started/quickstart.rst | 2 +- docs/source/guides/function_calling.rst | 80 +++--------------- 8 files changed, 31 insertions(+), 77 deletions(-) create mode 100644 docs/source/_static/img/arch_network_diagram_high_level.png diff --git a/README.md b/README.md index c35ebcb8..c6200745 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,14 @@ Engineered with purpose-built LLMs, Arch handles the critical but undifferentiat **Core Features**: - Built on [Envoy](https://envoyproxy.io): Arch runs alongside application servers as a separate containerized process, and builds on top of Envoy's proven HTTP management and scalability features to handle ingress and egress traffic related to prompts and LLMs. - - Function Calling for fast Agents and RAG apps. Engineered with purpose-built [LLMs](https://huggingface.co/collections/katanemo/arch-function-66f209a693ea8df14317ad68) to handle fast, cost-effective, and accurate prompt-based tasks like function/API calling, and parameter extraction from prompts. + - Intent Routing & Fast Function Calling. Engineered with purpose-built [LLMs](https://huggingface.co/collections/katanemo/arch-function-66f209a693ea8df14317ad68) to handle fast, cost-effective, and accurate prompt-based tasks like function/API calling, and parameter extraction from prompts to build smarter more accurate agentic applications. - Prompt [Guard](https://huggingface.co/collections/katanemo/arch-guard-6702bdc08b889e4bce8f446d): Arch centralizes guardrails to prevent jailbreak attempts and ensure safe user interactions without writing a single line of code. - - Routing & Traffic Management: Arch manages LLM calls, offering smart retries, automatic cutover, and resilient upstream connections for continuous availability. + - Routing & Traffic Management: Arch centralizes calls to LLMs used by your applications, offering smart retries, automatic cutover, and resilient upstream connections for continuous availability. - Observability: Arch uses the W3C Trace Context standard to enable complete request tracing across applications, ensuring compatibility with observability tools, and provides metrics to monitor latency, token usage, and error rates, helping optimize AI application performance. +**High-Level Network Flow**: +![alt text](docs/source/_static/img/arch_network_diagram_high_level.png) + **Jump to our [docs](https://docs.archgw.com)** to learn how you can use Arch to improve the speed, security and personalization of your GenAI apps. > [!IMPORTANT] @@ -57,7 +60,7 @@ Arch's CLI allows you to manage and interact with the Arch gateway efficiently. ```console $ python -m venv venv $ source venv/bin/activate # On Windows, use: venv\Scripts\activate -$ pip install archgw==0.1.7 +$ pip install archgw==0.1.8 ``` ### Build AI Agent with Arch Gateway diff --git a/arch/tools/README.md b/arch/tools/README.md index a679520e..f8cfc0b3 100644 --- a/arch/tools/README.md +++ b/arch/tools/README.md @@ -19,7 +19,7 @@ source venv/bin/activate ### Step 3: Run the build script ```bash -pip install archgw==0.1.7 +pip install archgw==0.1.8 ``` ## Uninstall Instructions: archgw CLI diff --git a/docs/source/_static/img/arch_network_diagram_high_level.png b/docs/source/_static/img/arch_network_diagram_high_level.png new file mode 100644 index 0000000000000000000000000000000000000000..8a66686f726d83ce9666cefe7116f8b5b7e63491 GIT binary patch literal 155491 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�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

x1doAJZBF)J~eKXTZ~SMgt=+4;fBt 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 literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py index 7151fee7..8359b195 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -13,9 +13,9 @@ from sphinxawesome_theme import ThemeOptions from sphinxawesome_theme.postprocess import Icons project = "Arch Docs" -copyright = "2024, Katanemo Labs, Inc" +copyright = "2025, Katanemo Labs, Inc" author = "Katanemo Labs, Inc" -release = " v0.1.7" +release = " v0.1.8" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/docs/source/get_started/intro_to_arch.rst b/docs/source/get_started/intro_to_arch.rst index 9bd78f1e..97188ab1 100644 --- a/docs/source/get_started/intro_to_arch.rst +++ b/docs/source/get_started/intro_to_arch.rst @@ -8,10 +8,13 @@ Engineered with purpose-built large language models (LLMs), Arch handles all the detecting and rejecting jailbreak attempts, intelligently calling “backend” APIs to fulfill the user's request represented in a prompt, routing to and offering disaster recovery between upstream LLMs, and managing the observability of prompts and LLM interactions in a centralized way. -.. image:: /_static/img/arch-logo.png +.. figure:: /_static/img/arch_network_diagram_high_level.png :width: 100% :align: center + High-level network flow of where Arch Gateway sits in your agentic stack. Designed for both ingress and egress prompt traffic. + + **The project was born out of the belief that:** *Prompts are nuanced and opaque user requests, which require the same capabilities as traditional HTTP requests diff --git a/docs/source/get_started/overview.rst b/docs/source/get_started/overview.rst index 60b63b1f..07a347af 100644 --- a/docs/source/get_started/overview.rst +++ b/docs/source/get_started/overview.rst @@ -7,6 +7,12 @@ Welcome to Arch, the intelligent prompt gateway designed to help developers buil In this documentation, you will learn how to quickly set up Arch to trigger API calls via prompts, apply prompt guardrails without writing any application-level logic, simplify the interaction with upstream LLMs, and improve observability all while simplifying your application development process. +.. figure:: /_static/img/arch_network_diagram_high_level.png + :width: 100% + :align: center + + High-level network flow of where Arch Gateway sits in your agentic stack. Designed for both ingress and egress prompt traffic. + Get Started ----------- diff --git a/docs/source/get_started/quickstart.rst b/docs/source/get_started/quickstart.rst index 1e572544..fd9f592c 100644 --- a/docs/source/get_started/quickstart.rst +++ b/docs/source/get_started/quickstart.rst @@ -25,7 +25,7 @@ Arch's CLI allows you to manage and interact with the Arch gateway efficiently. $ python -m venv venv $ source venv/bin/activate # On Windows, use: venv\Scripts\activate - $ pip install archgw==0.1.7 + $ pip install archgw==0.1.8 Build AI Agent with Arch Gateway diff --git a/docs/source/guides/function_calling.rst b/docs/source/guides/function_calling.rst index cb09bc6b..036d0e00 100644 --- a/docs/source/guides/function_calling.rst +++ b/docs/source/guides/function_calling.rst @@ -61,21 +61,6 @@ Key Features Parallel & Multiple Perform both parallel and multiple function calling ========================= =============================================================== - -Supported Languages -~~~~~~~~~~~~~~~~~~~ -.. table:: - :width: 100% - - ========================= =========================================================================================================================================== - **Language** **Data Type** - ========================= =========================================================================================================================================== - Python ``int``, ``str``, ``float``, ``bool``, ``list``, ``set``, ``dict``, ``tuple`` - Java ``byte``, ``short``, ``int``, ``long``, ``float``, ``double``, ``boolean``, ``char``, ``Array``, ``ArrayList``, ``Set``, ``HashMap``, ``Hashtable``, ``Queue``, ``Stack`` - Javascript ``Number``, ``Bigint``, ``String``, ``Boolean``, ``Object``, ``Array``, ``Date`` - ========================= =========================================================================================================================================== - - Implementing Function Calling ----------------------------- @@ -86,7 +71,6 @@ Step 1: Define the Function First, create or identify the backend function you want Arch to call. This could be an API endpoint, a script, or any other executable backend logic. .. code-block:: python - :caption: Example Function import requests @@ -136,63 +120,21 @@ Specify the parameters your function needs and how Arch should interpret these. Step 3: Arch Takes Over ~~~~~~~~~~~~~~~~~~~~~~~ -Once you have defined the functions and configured the prompt targets, Arch takes care of the remaining work. -It will automatically validate parameters validate parameters and ensure that the required parameters (e.g., location) are present in the prompt, and add validation rules if necessary. -Here is ane example validation schema using the `jsonschema `_ library +Once you have defined the functions and configured the prompt targets, Arch Gateway takes care of the remaining work. +It will automatically validate parameters, and ensure that the required parameters (e.g., location) are present in the prompt, and add validation rules if necessary. -.. code-block:: python - :caption: Example Validation Schema +.. figure:: /_static/img/arch_network_diagram_high_level.png + :width: 100% + :align: center - import requests - from jsonschema import validate, ValidationError - - # Define the JSON Schema for parameter validation - weather_validation_schema = { - "type": "object", - "properties": { - "location": { - "type": "string", - "minLength": 1, - "description": "The city and state, e.g. 'San Francisco, New York'" - }, - "unit": { - "type": "string", - "enum": ["celsius", "fahrenheit"], - "description": "The unit of temperature to return" - } - }, - "required": ["location"], - "additionalProperties": False - } - - def get_weather(location: str, unit: str = "fahrenheit"): - # Create the data object for validation - params = { - "location": location, - "unit": unit - } - - # Validate parameters using JSON Schema - try: - validate(instance=params, schema=weather_validation_schema) - except ValidationError as e: - raise ValueError(f"Invalid input: {e.message}") - - # Prepare the API request - api_server = "https://api.yourweatherapp.com" - endpoint = f"{api_server}/weather" - - # Make the API request - response = requests.get(endpoint, params=params) - return response.json() - - # Example usage - weather_info = get_weather("Seattle, WA", "celsius") - print(weather_info) + High-level network flow of where Arch Gateway sits in your agentic stack. Managing incoming and outgoing prompt traffic -Once the functions are called, Arch formats the response and deliver back to users. -By completing these setup steps, you enable Arch to manage the process from validation to response, ensuring users receive consistent, reliable results. +Once a downstream function (API) is called, Arch Gateway takes the response and sends it an upstream LLM to complete the request (for summarization, Q/A, text generation tasks). +For more details on how Arch Gateway enables you to centralize usage of LLMs, please read :ref:`LLM providers `. + +By completing these steps, you enable Arch to manage the process from validation to response, ensuring users receive consistent, reliable results - and that you are focused +on the stuff that matters most. Example Use Cases ----------------- From 88a02dc4787a8e5ae4570d3bfd27b2b42a9954c2 Mon Sep 17 00:00:00 2001 From: Shuguang Chen <54548843+nehcgs@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:45:36 -0800 Subject: [PATCH 03/18] Some fixes on model server (#362) * Some fixes on model server * Remove prompt_prefilling message * Fix logging * Fix poetry issues * Improve logging and update the support for text truncation * Fix tests * Fix tests * Fix tests * Fix modelserver tests * Update modelserver tests --- arch/tools/poetry.lock | 566 +++--------- arch/tools/pyproject.toml | 9 +- archgw.code-workspace | 6 +- model_server/poetry.lock | 842 ++++++++---------- model_server/pyproject.toml | 16 +- model_server/src/cli.py | 140 ++- model_server/src/commons/globals.py | 6 +- model_server/src/commons/utils.py | 81 +- model_server/src/core/function_calling.py | 204 ++--- model_server/src/core/guardrails.py | 63 +- model_server/src/core/utils/__init__.py | 0 .../hallucination_utils.py} | 12 +- .../src/core/{ => utils}/model_utils.py | 44 +- model_server/src/main.py | 110 +-- .../tests/core/test_function_calling.py | 15 +- model_server/tests/core/test_guardrails.py | 27 - model_server/tests/test_app.py | 6 - tests/modelserver/poetry.lock | 413 +++++---- tests/modelserver/pyproject.toml | 2 +- tests/modelserver/test_hallucination.py | 12 +- .../modelserver/test_hallucination_data.yaml | 29 +- tests/modelserver/test_modelserver.py | 7 +- tests/modelserver/test_success_data.yaml | 89 +- tests/rest/api_model_server.rest | 53 +- tests/rest/insurance_agent.rest | 4 - 25 files changed, 1090 insertions(+), 1666 deletions(-) create mode 100644 model_server/src/core/utils/__init__.py rename model_server/src/core/{hallucination.py => utils/hallucination_utils.py} (97%) rename model_server/src/core/{ => utils}/model_utils.py (77%) diff --git a/arch/tools/poetry.lock b/arch/tools/poetry.lock index 3e7c46b9..81ab0a39 100644 --- a/arch/tools/poetry.lock +++ b/arch/tools/poetry.lock @@ -1,19 +1,8 @@ -# 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"}, -] +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "archgw_modelserver" -version = "0.1.7" +version = "0.1.8" description = "A model server for serving models" optional = false python-versions = "*" @@ -56,127 +45,114 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -215,95 +191,6 @@ docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"] ssh = ["paramiko (>=2.4.3)"] websockets = ["websocket-client (>=1.3.0)"] -[[package]] -name = "filelock" -version = "3.16.1" -description = "A platform independent file lock." -optional = false -python-versions = ">=3.8" -files = [ - {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, - {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, -] - -[package.extras] -docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] -typing = ["typing-extensions (>=4.12.2)"] - -[[package]] -name = "fsspec" -version = "2024.10.0" -description = "File-system specification" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, - {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, -] - -[package.extras] -abfs = ["adlfs"] -adl = ["adlfs"] -arrow = ["pyarrow (>=1)"] -dask = ["dask", "distributed"] -dev = ["pre-commit", "ruff"] -doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"] -dropbox = ["dropbox", "dropboxdrivefs", "requests"] -full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] -fuse = ["fusepy"] -gcs = ["gcsfs"] -git = ["pygit2"] -github = ["requests"] -gs = ["gcsfs"] -gui = ["panel"] -hdfs = ["pyarrow (>=1)"] -http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"] -libarchive = ["libarchive-c"] -oci = ["ocifs"] -s3 = ["s3fs"] -sftp = ["paramiko"] -smb = ["smbprotocol"] -ssh = ["paramiko"] -test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"] -test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask-expr", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"] -test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard"] -tqdm = ["tqdm"] - -[[package]] -name = "huggingface-hub" -version = "0.26.5" -description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "huggingface_hub-0.26.5-py3-none-any.whl", hash = "sha256:fb7386090bbe892072e64b85f7c4479fd2d65eea5f2543327c970d5169e83924"}, - {file = "huggingface_hub-0.26.5.tar.gz", hash = "sha256:1008bd18f60bfb65e8dbc0a97249beeeaa8c99d3c2fa649354df9fa5a13ed83b"}, -] - -[package.dependencies] -filelock = "*" -fsspec = ">=2023.5.0" -packaging = ">=20.9" -pyyaml = ">=5.1" -requests = "*" -tqdm = ">=4.42.1" -typing-extensions = ">=3.7.4.3" - -[package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "libcst (==1.4.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] -fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] -hf-transfer = ["hf-transfer (>=0.1.4)"] -inference = ["aiohttp"] -quality = ["libcst (==1.4.0)", "mypy (==1.5.1)", "ruff (>=0.5.0)"] -tensorflow = ["graphviz", "pydot", "tensorflow"] -tensorflow-testing = ["keras (<3.0)", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio (>=4.0.0)", "jedi", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["safetensors[torch]", "torch"] -typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] - [[package]] name = "idna" version = "3.10" @@ -320,13 +207,13 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2 [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -440,149 +327,6 @@ files = [ {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] -[[package]] -name = "packaging" -version = "24.2" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, - {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, -] - -[[package]] -name = "pydantic" -version = "2.10.3" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, - {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, -] - -[package.dependencies] -annotated-types = ">=0.6.0" -pydantic-core = "2.27.1" -typing-extensions = ">=4.12.2" - -[package.extras] -email = ["email-validator (>=2.0.0)"] -timezone = ["tzdata"] - -[[package]] -name = "pydantic-core" -version = "2.27.1" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, - {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, - {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, - {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, - {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, - {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, - {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, - {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, - {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, - {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, - {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, - {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, - {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, - {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, - {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, - {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, - {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, - {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, - {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, - {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, - {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, - {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, - {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, - {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, - {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, - {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, - {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, - {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, - {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, - {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, - {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, - {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, - {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, - {file = "pydantic_core-2.27.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:5897bec80a09b4084aee23f9b73a9477a46c3304ad1d2d07acca19723fb1de62"}, - {file = "pydantic_core-2.27.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d0165ab2914379bd56908c02294ed8405c252250668ebcb438a55494c69f44ab"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b9af86e1d8e4cfc82c2022bfaa6f459381a50b94a29e95dcdda8442d6d83864"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f6c8a66741c5f5447e047ab0ba7a1c61d1e95580d64bce852e3df1f895c4067"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a42d6a8156ff78981f8aa56eb6394114e0dedb217cf8b729f438f643608cbcd"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64c65f40b4cd8b0e049a8edde07e38b476da7e3aaebe63287c899d2cff253fa5"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdcf339322a3fae5cbd504edcefddd5a50d9ee00d968696846f089b4432cf78"}, - {file = "pydantic_core-2.27.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bf99c8404f008750c846cb4ac4667b798a9f7de673ff719d705d9b2d6de49c5f"}, - {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f1edcea27918d748c7e5e4d917297b2a0ab80cad10f86631e488b7cddf76a36"}, - {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_armv7l.whl", hash = "sha256:159cac0a3d096f79ab6a44d77a961917219707e2a130739c64d4dd46281f5c2a"}, - {file = "pydantic_core-2.27.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:029d9757eb621cc6e1848fa0b0310310de7301057f623985698ed7ebb014391b"}, - {file = "pydantic_core-2.27.1-cp38-none-win32.whl", hash = "sha256:a28af0695a45f7060e6f9b7092558a928a28553366519f64083c63a44f70e618"}, - {file = "pydantic_core-2.27.1-cp38-none-win_amd64.whl", hash = "sha256:2d4567c850905d5eaaed2f7a404e61012a51caf288292e016360aa2b96ff38d4"}, - {file = "pydantic_core-2.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:e9386266798d64eeb19dd3677051f5705bf873e98e15897ddb7d76f477131967"}, - {file = "pydantic_core-2.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4228b5b646caa73f119b1ae756216b59cc6e2267201c27d3912b592c5e323b60"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3dfe500de26c52abe0477dde16192ac39c98f05bf2d80e76102d394bd13854"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aee66be87825cdf72ac64cb03ad4c15ffef4143dbf5c113f64a5ff4f81477bf9"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b748c44bb9f53031c8cbc99a8a061bc181c1000c60a30f55393b6e9c45cc5bd"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ca038c7f6a0afd0b2448941b6ef9d5e1949e999f9e5517692eb6da58e9d44be"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e0bd57539da59a3e4671b90a502da9a28c72322a4f17866ba3ac63a82c4498e"}, - {file = "pydantic_core-2.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac6c2c45c847bbf8f91930d88716a0fb924b51e0c6dad329b793d670ec5db792"}, - {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b94d4ba43739bbe8b0ce4262bcc3b7b9f31459ad120fb595627eaeb7f9b9ca01"}, - {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:00e6424f4b26fe82d44577b4c842d7df97c20be6439e8e685d0d715feceb9fb9"}, - {file = "pydantic_core-2.27.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:38de0a70160dd97540335b7ad3a74571b24f1dc3ed33f815f0880682e6880131"}, - {file = "pydantic_core-2.27.1-cp39-none-win32.whl", hash = "sha256:7ccebf51efc61634f6c2344da73e366c75e735960b5654b63d7e6f69a5885fa3"}, - {file = "pydantic_core-2.27.1-cp39-none-win_amd64.whl", hash = "sha256:a57847b090d7892f123726202b7daa20df6694cbd583b67a592e856bff603d6c"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, - {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5fde892e6c697ce3e30c61b239330fc5d569a71fefd4eb6512fc6caec9dd9e2f"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:816f5aa087094099fff7edabb5e01cc370eb21aa1a1d44fe2d2aefdfb5599b31"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c10c309e18e443ddb108f0ef64e8729363adbfd92d6d57beec680f6261556f3"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98476c98b02c8e9b2eec76ac4156fd006628b1b2d0ef27e548ffa978393fd154"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3027001c28434e7ca5a6e1e527487051136aa81803ac812be51802150d880dd"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7699b1df36a48169cdebda7ab5a2bac265204003f153b4bd17276153d997670a"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1c39b07d90be6b48968ddc8c19e7585052088fd7ec8d568bb31ff64c70ae3c97"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:46ccfe3032b3915586e469d4972973f893c0a2bb65669194a5bdea9bacc088c2"}, - {file = "pydantic_core-2.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:62ba45e21cf6571d7f716d903b5b7b6d2617e2d5d67c0923dc47b9d41369f840"}, - {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - [[package]] name = "python-dotenv" version = "1.0.1" @@ -624,68 +368,6 @@ files = [ {file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"}, ] -[[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 = "referencing" version = "0.35.1" @@ -854,47 +536,15 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib-metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] -[[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.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -905,5 +555,5 @@ zstd = ["zstandard (>=0.18.0)"] [metadata] lock-version = "2.0" -python-versions = "^3.12" -content-hash = "6016abef181ad0b4053e51b3b7de2ce5f1b852e8f4dd950eda8cde7294e70026" +python-versions = "^3.10" +content-hash = "ab027b62af1cbf96ef77b4db808824d66b09b065f1b18d215bdc6110eb766d10" diff --git a/arch/tools/pyproject.toml b/arch/tools/pyproject.toml index 24410562..008c967c 100644 --- a/arch/tools/pyproject.toml +++ b/arch/tools/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "archgw" -version = "0.1.7" +version = "0.1.8" description = "Python-based CLI tool to manage Arch Gateway." authors = ["Katanemo Labs, Inc."] packages = [ @@ -9,15 +9,12 @@ packages = [ readme = "README.md" [tool.poetry.dependencies] -python = "^3.12" -archgw_modelserver = "0.1.7" -pyyaml = "^6.0.2" -pydantic = "^2.10.1" +python = "^3.10" +archgw_modelserver = "^0.1.8" click = "^8.1.7" jinja2 = "^3.1.4" jsonschema = "^4.23.0" setuptools = "75.5.0" -huggingface_hub = "^0.26.0" docker = "^7.1.0" python-dotenv = "^1.0.1" diff --git a/archgw.code-workspace b/archgw.code-workspace index 3c968e72..50c8a492 100644 --- a/archgw.code-workspace +++ b/archgw.code-workspace @@ -1,9 +1,9 @@ { "folders": [ - { + { "name": "root", - "path": "." - }, + "path": "." + }, { "name": "crates", "path": "crates" diff --git a/model_server/poetry.lock b/model_server/poetry.lock index 805ba667..c08f77ca 100644 --- a/model_server/poetry.lock +++ b/model_server/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "accelerate" @@ -44,23 +44,24 @@ files = [ [[package]] name = "anyio" -version = "4.7.0" +version = "4.8.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" files = [ - {file = "anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352"}, - {file = "anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48"}, + {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, + {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, ] [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] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -74,6 +75,9 @@ files = [ {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, ] +[package.dependencies] +typing-extensions = {version = ">=4", markers = "python_version < \"3.11\""} + [package.extras] tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] @@ -90,127 +94,114 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, + {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, + {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, ] [package.dependencies] @@ -277,6 +268,20 @@ files = [ {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, ] +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "fastapi" version = "0.115.0" @@ -315,13 +320,13 @@ typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "fsspec" -version = "2024.10.0" +version = "2024.12.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, - {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, + {file = "fsspec-2024.12.0-py3-none-any.whl", hash = "sha256:b520aed47ad9804237ff878b504267a3b0b441e97508bd6d2d8774e3db85cee2"}, + {file = "fsspec-2024.12.0.tar.gz", hash = "sha256:670700c977ed2fb51e0d9f9253177ed20cbde4a3e5c0283cc5385b5870c8533f"}, ] [package.extras] @@ -371,70 +376,70 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "grpcio" -version = "1.68.1" +version = "1.69.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.68.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d"}, - {file = "grpcio-1.68.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e"}, - {file = "grpcio-1.68.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330"}, - {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079"}, - {file = "grpcio-1.68.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1"}, - {file = "grpcio-1.68.1-cp310-cp310-win32.whl", hash = "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5"}, - {file = "grpcio-1.68.1-cp310-cp310-win_amd64.whl", hash = "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746"}, - {file = "grpcio-1.68.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c"}, - {file = "grpcio-1.68.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd"}, - {file = "grpcio-1.68.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600"}, - {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe"}, - {file = "grpcio-1.68.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0"}, - {file = "grpcio-1.68.1-cp311-cp311-win32.whl", hash = "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9"}, - {file = "grpcio-1.68.1-cp311-cp311-win_amd64.whl", hash = "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2"}, - {file = "grpcio-1.68.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666"}, - {file = "grpcio-1.68.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e"}, - {file = "grpcio-1.68.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60"}, - {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475"}, - {file = "grpcio-1.68.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613"}, - {file = "grpcio-1.68.1-cp312-cp312-win32.whl", hash = "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5"}, - {file = "grpcio-1.68.1-cp312-cp312-win_amd64.whl", hash = "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c"}, - {file = "grpcio-1.68.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385"}, - {file = "grpcio-1.68.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54"}, - {file = "grpcio-1.68.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a"}, - {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161"}, - {file = "grpcio-1.68.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad"}, - {file = "grpcio-1.68.1-cp313-cp313-win32.whl", hash = "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172"}, - {file = "grpcio-1.68.1-cp313-cp313-win_amd64.whl", hash = "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e"}, - {file = "grpcio-1.68.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad"}, - {file = "grpcio-1.68.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf"}, - {file = "grpcio-1.68.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e"}, - {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c"}, - {file = "grpcio-1.68.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded"}, - {file = "grpcio-1.68.1-cp38-cp38-win32.whl", hash = "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63"}, - {file = "grpcio-1.68.1-cp38-cp38-win_amd64.whl", hash = "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d"}, - {file = "grpcio-1.68.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a"}, - {file = "grpcio-1.68.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9"}, - {file = "grpcio-1.68.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0"}, - {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e"}, - {file = "grpcio-1.68.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43"}, - {file = "grpcio-1.68.1-cp39-cp39-win32.whl", hash = "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76"}, - {file = "grpcio-1.68.1-cp39-cp39-win_amd64.whl", hash = "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1"}, - {file = "grpcio-1.68.1.tar.gz", hash = "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054"}, + {file = "grpcio-1.69.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97"}, + {file = "grpcio-1.69.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e"}, + {file = "grpcio-1.69.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e"}, + {file = "grpcio-1.69.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51"}, + {file = "grpcio-1.69.0-cp310-cp310-win32.whl", hash = "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc"}, + {file = "grpcio-1.69.0-cp310-cp310-win_amd64.whl", hash = "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5"}, + {file = "grpcio-1.69.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561"}, + {file = "grpcio-1.69.0-cp311-cp311-macosx_10_14_universal2.whl", hash = "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c"}, + {file = "grpcio-1.69.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d"}, + {file = "grpcio-1.69.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2"}, + {file = "grpcio-1.69.0-cp311-cp311-win32.whl", hash = "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258"}, + {file = "grpcio-1.69.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7"}, + {file = "grpcio-1.69.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b"}, + {file = "grpcio-1.69.0-cp312-cp312-macosx_10_14_universal2.whl", hash = "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084"}, + {file = "grpcio-1.69.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d"}, + {file = "grpcio-1.69.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55"}, + {file = "grpcio-1.69.0-cp312-cp312-win32.whl", hash = "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1"}, + {file = "grpcio-1.69.0-cp312-cp312-win_amd64.whl", hash = "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01"}, + {file = "grpcio-1.69.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:a78a06911d4081a24a1761d16215a08e9b6d4d29cdbb7e427e6c7e17b06bcc5d"}, + {file = "grpcio-1.69.0-cp313-cp313-macosx_10_14_universal2.whl", hash = "sha256:dc5a351927d605b2721cbb46158e431dd49ce66ffbacb03e709dc07a491dde35"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:3629d8a8185f5139869a6a17865d03113a260e311e78fbe313f1a71603617589"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9a281878feeb9ae26db0622a19add03922a028d4db684658f16d546601a4870"}, + {file = "grpcio-1.69.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc614e895177ab7e4b70f154d1a7c97e152577ea101d76026d132b7aaba003b"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:1ee76cd7e2e49cf9264f6812d8c9ac1b85dda0eaea063af07292400f9191750e"}, + {file = "grpcio-1.69.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:0470fa911c503af59ec8bc4c82b371ee4303ececbbdc055f55ce48e38b20fd67"}, + {file = "grpcio-1.69.0-cp313-cp313-win32.whl", hash = "sha256:b650f34aceac8b2d08a4c8d7dc3e8a593f4d9e26d86751ebf74ebf5107d927de"}, + {file = "grpcio-1.69.0-cp313-cp313-win_amd64.whl", hash = "sha256:028337786f11fecb5d7b7fa660475a06aabf7e5e52b5ac2df47414878c0ce7ea"}, + {file = "grpcio-1.69.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:b7f693db593d6bf285e015d5538bf1c86cf9c60ed30b6f7da04a00ed052fe2f3"}, + {file = "grpcio-1.69.0-cp38-cp38-macosx_10_14_universal2.whl", hash = "sha256:8b94e83f66dbf6fd642415faca0608590bc5e8d30e2c012b31d7d1b91b1de2fd"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:b634851b92c090763dde61df0868c730376cdb73a91bcc821af56ae043b09596"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf5f680d3ed08c15330d7830d06bc65f58ca40c9999309517fd62880d70cb06e"}, + {file = "grpcio-1.69.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:200e48a6e7b00f804cf00a1c26292a5baa96507c7749e70a3ec10ca1a288936e"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:45a4704339b6e5b24b0e136dea9ad3815a94f30eb4f1e1d44c4ac484ef11d8dd"}, + {file = "grpcio-1.69.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85d347cb8237751b23539981dbd2d9d8f6e9ff90082b427b13022b948eb6347a"}, + {file = "grpcio-1.69.0-cp38-cp38-win32.whl", hash = "sha256:60e5de105dc02832dc8f120056306d0ef80932bcf1c0e2b4ca3b676de6dc6505"}, + {file = "grpcio-1.69.0-cp38-cp38-win_amd64.whl", hash = "sha256:282f47d0928e40f25d007f24eb8fa051cb22551e3c74b8248bc9f9bea9c35fe0"}, + {file = "grpcio-1.69.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:dd034d68a2905464c49479b0c209c773737a4245d616234c79c975c7c90eca03"}, + {file = "grpcio-1.69.0-cp39-cp39-macosx_10_14_universal2.whl", hash = "sha256:01f834732c22a130bdf3dc154d1053bdbc887eb3ccb7f3e6285cfbfc33d9d5cc"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:a7f4ed0dcf202a70fe661329f8874bc3775c14bb3911d020d07c82c766ce0eb1"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd7ea241b10bc5f0bb0f82c0d7896822b7ed122b3ab35c9851b440c1ccf81588"}, + {file = "grpcio-1.69.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f03dc9b4da4c0dc8a1db7a5420f575251d7319b7a839004d8916257ddbe4816"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ca71d73a270dff052fe4edf74fef142d6ddd1f84175d9ac4a14b7280572ac519"}, + {file = "grpcio-1.69.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ccbed100dc43704e94ccff9e07680b540d64e4cc89213ab2832b51b4f68a520"}, + {file = "grpcio-1.69.0-cp39-cp39-win32.whl", hash = "sha256:1514341def9c6ec4b7f0b9628be95f620f9d4b99331b7ef0a1845fd33d9b579c"}, + {file = "grpcio-1.69.0-cp39-cp39-win_amd64.whl", hash = "sha256:c1fea55d26d647346acb0069b08dca70984101f2dc95066e003019207212e303"}, + {file = "grpcio-1.69.0.tar.gz", hash = "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.68.1)"] +protobuf = ["grpcio-tools (>=1.69.0)"] [[package]] name = "h11" @@ -495,13 +500,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "huggingface-hub" -version = "0.27.0" +version = "0.27.1" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.27.0-py3-none-any.whl", hash = "sha256:8f2e834517f1f1ddf1ecc716f91b120d7333011b7485f665a9a412eacb1a2a81"}, - {file = "huggingface_hub-0.27.0.tar.gz", hash = "sha256:902cce1a1be5739f5589e560198a65a8edcfd3b830b1666f36e4b961f0454fac"}, + {file = "huggingface_hub-0.27.1-py3-none-any.whl", hash = "sha256:1c5155ca7d60b60c2e2fc38cbb3ffb7f7c3adf48f824015b219af9061771daec"}, + {file = "huggingface_hub-0.27.1.tar.gz", hash = "sha256:c004463ca870283909d715d20f066ebd6968c2207dae9393fdffb3c1d4d8f98b"}, ] [package.dependencies] @@ -577,13 +582,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.5" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, - {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, + {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, + {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, ] [package.dependencies] @@ -785,66 +790,66 @@ test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "numpy" -version = "2.2.0" +version = "2.2.1" description = "Fundamental package for array computing in Python" optional = false python-versions = ">=3.10" files = [ - {file = "numpy-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e25507d85da11ff5066269d0bd25d06e0a0f2e908415534f3e603d2a78e4ffa"}, - {file = "numpy-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a62eb442011776e4036af5c8b1a00b706c5bc02dc15eb5344b0c750428c94219"}, - {file = "numpy-2.2.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:b606b1aaf802e6468c2608c65ff7ece53eae1a6874b3765f69b8ceb20c5fa78e"}, - {file = "numpy-2.2.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:36b2b43146f646642b425dd2027730f99bac962618ec2052932157e213a040e9"}, - {file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fe8f3583e0607ad4e43a954e35c1748b553bfe9fdac8635c02058023277d1b3"}, - {file = "numpy-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:122fd2fcfafdefc889c64ad99c228d5a1f9692c3a83f56c292618a59aa60ae83"}, - {file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3f2f5cddeaa4424a0a118924b988746db6ffa8565e5829b1841a8a3bd73eb59a"}, - {file = "numpy-2.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7fe4bb0695fe986a9e4deec3b6857003b4cfe5c5e4aac0b95f6a658c14635e31"}, - {file = "numpy-2.2.0-cp310-cp310-win32.whl", hash = "sha256:b30042fe92dbd79f1ba7f6898fada10bdaad1847c44f2dff9a16147e00a93661"}, - {file = "numpy-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dc1d6d66f8d37843ed281773c7174f03bf7ad826523f73435deb88ba60d2d4"}, - {file = "numpy-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9874bc2ff574c40ab7a5cbb7464bf9b045d617e36754a7bc93f933d52bd9ffc6"}, - {file = "numpy-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0da8495970f6b101ddd0c38ace92edea30e7e12b9a926b57f5fabb1ecc25bb90"}, - {file = "numpy-2.2.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0557eebc699c1c34cccdd8c3778c9294e8196df27d713706895edc6f57d29608"}, - {file = "numpy-2.2.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:3579eaeb5e07f3ded59298ce22b65f877a86ba8e9fe701f5576c99bb17c283da"}, - {file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40deb10198bbaa531509aad0cd2f9fadb26c8b94070831e2208e7df543562b74"}, - {file = "numpy-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2aed8fcf8abc3020d6a9ccb31dbc9e7d7819c56a348cc88fd44be269b37427e"}, - {file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a222d764352c773aa5ebde02dd84dba3279c81c6db2e482d62a3fa54e5ece69b"}, - {file = "numpy-2.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4e58666988605e251d42c2818c7d3d8991555381be26399303053b58a5bbf30d"}, - {file = "numpy-2.2.0-cp311-cp311-win32.whl", hash = "sha256:4723a50e1523e1de4fccd1b9a6dcea750c2102461e9a02b2ac55ffeae09a4410"}, - {file = "numpy-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:16757cf28621e43e252c560d25b15f18a2f11da94fea344bf26c599b9cf54b73"}, - {file = "numpy-2.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cff210198bb4cae3f3c100444c5eaa573a823f05c253e7188e1362a5555235b3"}, - {file = "numpy-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:58b92a5828bd4d9aa0952492b7de803135038de47343b2aa3cc23f3b71a3dc4e"}, - {file = "numpy-2.2.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:ebe5e59545401fbb1b24da76f006ab19734ae71e703cdb4a8b347e84a0cece67"}, - {file = "numpy-2.2.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:e2b8cd48a9942ed3f85b95ca4105c45758438c7ed28fff1e4ce3e57c3b589d8e"}, - {file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57fcc997ffc0bef234b8875a54d4058afa92b0b0c4223fc1f62f24b3b5e86038"}, - {file = "numpy-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ad7d11b309bd132d74397fcf2920933c9d1dc865487128f5c03d580f2c3d03"}, - {file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cb24cca1968b21355cc6f3da1a20cd1cebd8a023e3c5b09b432444617949085a"}, - {file = "numpy-2.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0798b138c291d792f8ea40fe3768610f3c7dd2574389e37c3f26573757c8f7ef"}, - {file = "numpy-2.2.0-cp312-cp312-win32.whl", hash = "sha256:afe8fb968743d40435c3827632fd36c5fbde633b0423da7692e426529b1759b1"}, - {file = "numpy-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a4199f519e57d517ebd48cb76b36c82da0360781c6a0353e64c0cac30ecaad3"}, - {file = "numpy-2.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f8c8b141ef9699ae777c6278b52c706b653bf15d135d302754f6b2e90eb30367"}, - {file = "numpy-2.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f0986e917aca18f7a567b812ef7ca9391288e2acb7a4308aa9d265bd724bdae"}, - {file = "numpy-2.2.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:1c92113619f7b272838b8d6702a7f8ebe5edea0df48166c47929611d0b4dea69"}, - {file = "numpy-2.2.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5a145e956b374e72ad1dff82779177d4a3c62bc8248f41b80cb5122e68f22d13"}, - {file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18142b497d70a34b01642b9feabb70156311b326fdddd875a9981f34a369b671"}, - {file = "numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d41d1612c1a82b64697e894b75db6758d4f21c3ec069d841e60ebe54b5b571"}, - {file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a98f6f20465e7618c83252c02041517bd2f7ea29be5378f09667a8f654a5918d"}, - {file = "numpy-2.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e09d40edfdb4e260cb1567d8ae770ccf3b8b7e9f0d9b5c2a9992696b30ce2742"}, - {file = "numpy-2.2.0-cp313-cp313-win32.whl", hash = "sha256:3905a5fffcc23e597ee4d9fb3fcd209bd658c352657548db7316e810ca80458e"}, - {file = "numpy-2.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:a184288538e6ad699cbe6b24859206e38ce5fba28f3bcfa51c90d0502c1582b2"}, - {file = "numpy-2.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7832f9e8eb00be32f15fdfb9a981d6955ea9adc8574c521d48710171b6c55e95"}, - {file = "numpy-2.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f0dd071b95bbca244f4cb7f70b77d2ff3aaaba7fa16dc41f58d14854a6204e6c"}, - {file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0b227dcff8cdc3efbce66d4e50891f04d0a387cce282fe1e66199146a6a8fca"}, - {file = "numpy-2.2.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ab153263a7c5ccaf6dfe7e53447b74f77789f28ecb278c3b5d49db7ece10d6d"}, - {file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e500aba968a48e9019e42c0c199b7ec0696a97fa69037bea163b55398e390529"}, - {file = "numpy-2.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:440cfb3db4c5029775803794f8638fbdbf71ec702caf32735f53b008e1eaece3"}, - {file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a55dc7a7f0b6198b07ec0cd445fbb98b05234e8b00c5ac4874a63372ba98d4ab"}, - {file = "numpy-2.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4bddbaa30d78c86329b26bd6aaaea06b1e47444da99eddac7bf1e2fab717bd72"}, - {file = "numpy-2.2.0-cp313-cp313t-win32.whl", hash = "sha256:30bf971c12e4365153afb31fc73f441d4da157153f3400b82db32d04de1e4066"}, - {file = "numpy-2.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d35717333b39d1b6bb8433fa758a55f1081543de527171543a2b710551d40881"}, - {file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e12c6c1ce84628c52d6367863773f7c8c8241be554e8b79686e91a43f1733773"}, - {file = "numpy-2.2.0-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:b6207dc8fb3c8cb5668e885cef9ec7f70189bec4e276f0ff70d5aa078d32c88e"}, - {file = "numpy-2.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a50aeff71d0f97b6450d33940c7181b08be1441c6c193e678211bff11aa725e7"}, - {file = "numpy-2.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:df12a1f99b99f569a7c2ae59aa2d31724e8d835fc7f33e14f4792e3071d11221"}, - {file = "numpy-2.2.0.tar.gz", hash = "sha256:140dd80ff8981a583a60980be1a655068f8adebf7a45a06a6858c873fcdcd4a0"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5edb4e4caf751c1518e6a26a83501fda79bff41cc59dac48d70e6d65d4ec4440"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa3017c40d513ccac9621a2364f939d39e550c542eb2a894b4c8da92b38896ab"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:61048b4a49b1c93fe13426e04e04fdf5a03f456616f6e98c7576144677598675"}, + {file = "numpy-2.2.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:7671dc19c7019103ca44e8d94917eba8534c76133523ca8406822efdd19c9308"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4250888bcb96617e00bfa28ac24850a83c9f3a16db471eca2ee1f1714df0f957"}, + {file = "numpy-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7746f235c47abc72b102d3bce9977714c2444bdfaea7888d241b4c4bb6a78bf"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:059e6a747ae84fce488c3ee397cee7e5f905fd1bda5fb18c66bc41807ff119b2"}, + {file = "numpy-2.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f62aa6ee4eb43b024b0e5a01cf65a0bb078ef8c395e8713c6e8a12a697144528"}, + {file = "numpy-2.2.1-cp310-cp310-win32.whl", hash = "sha256:48fd472630715e1c1c89bf1feab55c29098cb403cc184b4859f9c86d4fcb6a95"}, + {file = "numpy-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:b541032178a718c165a49638d28272b771053f628382d5e9d1c93df23ff58dbf"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40f9e544c1c56ba8f1cf7686a8c9b5bb249e665d40d626a23899ba6d5d9e1484"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9b57eaa3b0cd8db52049ed0330747b0364e899e8a606a624813452b8203d5f7"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bc8a37ad5b22c08e2dbd27df2b3ef7e5c0864235805b1e718a235bcb200cf1cb"}, + {file = "numpy-2.2.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9036d6365d13b6cbe8f27a0eaf73ddcc070cae584e5ff94bb45e3e9d729feab5"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51faf345324db860b515d3f364eaa93d0e0551a88d6218a7d61286554d190d73"}, + {file = "numpy-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38efc1e56b73cc9b182fe55e56e63b044dd26a72128fd2fbd502f75555d92591"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:31b89fa67a8042e96715c68e071a1200c4e172f93b0fbe01a14c0ff3ff820fc8"}, + {file = "numpy-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4c86e2a209199ead7ee0af65e1d9992d1dce7e1f63c4b9a616500f93820658d0"}, + {file = "numpy-2.2.1-cp311-cp311-win32.whl", hash = "sha256:b34d87e8a3090ea626003f87f9392b3929a7bbf4104a05b6667348b6bd4bf1cd"}, + {file = "numpy-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:360137f8fb1b753c5cde3ac388597ad680eccbbbb3865ab65efea062c4a1fd16"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:694f9e921a0c8f252980e85bce61ebbd07ed2b7d4fa72d0e4246f2f8aa6642ab"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3683a8d166f2692664262fd4900f207791d005fb088d7fdb973cc8d663626faa"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:780077d95eafc2ccc3ced969db22377b3864e5b9a0ea5eb347cc93b3ea900315"}, + {file = "numpy-2.2.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:55ba24ebe208344aa7a00e4482f65742969a039c2acfcb910bc6fcd776eb4355"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b1d07b53b78bf84a96898c1bc139ad7f10fda7423f5fd158fd0f47ec5e01ac7"}, + {file = "numpy-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5062dc1a4e32a10dc2b8b13cedd58988261416e811c1dc4dbdea4f57eea61b0d"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fce4f615f8ca31b2e61aa0eb5865a21e14f5629515c9151850aa936c02a1ee51"}, + {file = "numpy-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:67d4cda6fa6ffa073b08c8372aa5fa767ceb10c9a0587c707505a6d426f4e046"}, + {file = "numpy-2.2.1-cp312-cp312-win32.whl", hash = "sha256:32cb94448be47c500d2c7a95f93e2f21a01f1fd05dd2beea1ccd049bb6001cd2"}, + {file = "numpy-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:ba5511d8f31c033a5fcbda22dd5c813630af98c70b2661f2d2c654ae3cdfcfc8"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f1d09e520217618e76396377c81fba6f290d5f926f50c35f3a5f72b01a0da780"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ecc47cd7f6ea0336042be87d9e7da378e5c7e9b3c8ad0f7c966f714fc10d821"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f419290bc8968a46c4933158c91a0012b7a99bb2e465d5ef5293879742f8797e"}, + {file = "numpy-2.2.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b6c390bfaef8c45a260554888966618328d30e72173697e5cabe6b285fb2348"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:526fc406ab991a340744aad7e25251dd47a6720a685fa3331e5c59fef5282a59"}, + {file = "numpy-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e6fdeb9a265624ec3a3918430205dff1df7e95a230779746a6af78bc615af"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:53c09385ff0b72ba79d8715683c1168c12e0b6e84fb0372e97553d1ea91efe51"}, + {file = "numpy-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f3eac17d9ec51be534685ba877b6ab5edc3ab7ec95c8f163e5d7b39859524716"}, + {file = "numpy-2.2.1-cp313-cp313-win32.whl", hash = "sha256:9ad014faa93dbb52c80d8f4d3dcf855865c876c9660cb9bd7553843dd03a4b1e"}, + {file = "numpy-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:164a829b6aacf79ca47ba4814b130c4020b202522a93d7bff2202bfb33b61c60"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4dfda918a13cc4f81e9118dea249e192ab167a0bb1966272d5503e39234d694e"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:733585f9f4b62e9b3528dd1070ec4f52b8acf64215b60a845fa13ebd73cd0712"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:89b16a18e7bba224ce5114db863e7029803c179979e1af6ad6a6b11f70545008"}, + {file = "numpy-2.2.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:676f4eebf6b2d430300f1f4f4c2461685f8269f94c89698d832cdf9277f30b84"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f5cdf9f493b35f7e41e8368e7d7b4bbafaf9660cba53fb21d2cd174ec09631"}, + {file = "numpy-2.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1ad395cf254c4fbb5b2132fee391f361a6e8c1adbd28f2cd8e79308a615fe9d"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:08ef779aed40dbc52729d6ffe7dd51df85796a702afbf68a4f4e41fafdc8bda5"}, + {file = "numpy-2.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:26c9c4382b19fcfbbed3238a14abf7ff223890ea1936b8890f058e7ba35e8d71"}, + {file = "numpy-2.2.1-cp313-cp313t-win32.whl", hash = "sha256:93cf4e045bae74c90ca833cba583c14b62cb4ba2cba0abd2b141ab52548247e2"}, + {file = "numpy-2.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bff7d8ec20f5f42607599f9994770fa65d76edca264a87b5e4ea5629bce12268"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ba9cc93a91d86365a5d270dee221fdc04fb68d7478e6bf6af650de78a8339e3"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3d03883435a19794e41f147612a77a8f56d4e52822337844fff3d4040a142964"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4511d9e6071452b944207c8ce46ad2f897307910b402ea5fa975da32e0102800"}, + {file = "numpy-2.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5c5cc0cbabe9452038ed984d05ac87910f89370b9242371bd9079cb4af61811e"}, + {file = "numpy-2.2.1.tar.gz", hash = "sha256:45681fd7128c8ad1c379f0ca0776a8b0c6583d2f69889ddac01559dfe4390918"}, ] [[package]] @@ -993,13 +998,13 @@ files = [ [[package]] name = "openai" -version = "1.50.2" +version = "1.59.6" description = "The official Python library for the openai API" optional = false -python-versions = ">=3.7.1" +python-versions = ">=3.8" files = [ - {file = "openai-1.50.2-py3-none-any.whl", hash = "sha256:822dd2051baa3393d0d5406990611975dd6f533020dc9375a34d4fe67e8b75f7"}, - {file = "openai-1.50.2.tar.gz", hash = "sha256:3987ae027152fc8bea745d60b02c8f4c4a76e1b5c70e73565fa556db6f78c9e6"}, + {file = "openai-1.59.6-py3-none-any.whl", hash = "sha256:b28ed44eee3d5ebe1a3ea045ee1b4b50fea36ecd50741aaa5ce5a5559c900cb6"}, + {file = "openai-1.59.6.tar.gz", hash = "sha256:c7670727c2f1e4473f62fea6fa51475c8bc098c9ffb47bfb9eef5be23c747934"}, ] [package.dependencies] @@ -1014,6 +1019,7 @@ typing-extensions = ">=4.11,<5" [package.extras] datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] +realtime = ["websockets (>=13,<15)"] [[package]] name = "opentelemetry-api" @@ -1236,88 +1242,6 @@ files = [ {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] -[[package]] -name = "pandas" -version = "2.2.3" -description = "Powerful data structures for data analysis, time series, and statistics" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, - {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, - {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, - {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, - {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, - {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, - {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, - {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, -] - -[package.dependencies] -numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""} -python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" - -[package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] - [[package]] name = "pluggy" version = "1.5.0" @@ -1335,62 +1259,63 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "5.29.2" +version = "5.29.3" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-5.29.2-cp310-abi3-win32.whl", hash = "sha256:c12ba8249f5624300cf51c3d0bfe5be71a60c63e4dcf51ffe9a68771d958c851"}, - {file = "protobuf-5.29.2-cp310-abi3-win_amd64.whl", hash = "sha256:842de6d9241134a973aab719ab42b008a18a90f9f07f06ba480df268f86432f9"}, - {file = "protobuf-5.29.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a0c53d78383c851bfa97eb42e3703aefdc96d2036a41482ffd55dc5f529466eb"}, - {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:494229ecd8c9009dd71eda5fd57528395d1eacdf307dbece6c12ad0dd09e912e"}, - {file = "protobuf-5.29.2-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:b6b0d416bbbb9d4fbf9d0561dbfc4e324fd522f61f7af0fe0f282ab67b22477e"}, - {file = "protobuf-5.29.2-cp38-cp38-win32.whl", hash = "sha256:e621a98c0201a7c8afe89d9646859859be97cb22b8bf1d8eacfd90d5bda2eb19"}, - {file = "protobuf-5.29.2-cp38-cp38-win_amd64.whl", hash = "sha256:13d6d617a2a9e0e82a88113d7191a1baa1e42c2cc6f5f1398d3b054c8e7e714a"}, - {file = "protobuf-5.29.2-cp39-cp39-win32.whl", hash = "sha256:36000f97ea1e76e8398a3f02936aac2a5d2b111aae9920ec1b769fc4a222c4d9"}, - {file = "protobuf-5.29.2-cp39-cp39-win_amd64.whl", hash = "sha256:2d2e674c58a06311c8e99e74be43e7f3a8d1e2b2fdf845eaa347fbd866f23355"}, - {file = "protobuf-5.29.2-py3-none-any.whl", hash = "sha256:fde4554c0e578a5a0bcc9a276339594848d1e89f9ea47b4427c80e5d72f90181"}, - {file = "protobuf-5.29.2.tar.gz", hash = "sha256:b2cc8e8bb7c9326996f0e160137b0861f1a82162502658df2951209d0cb0309e"}, + {file = "protobuf-5.29.3-cp310-abi3-win32.whl", hash = "sha256:3ea51771449e1035f26069c4c7fd51fba990d07bc55ba80701c78f886bf9c888"}, + {file = "protobuf-5.29.3-cp310-abi3-win_amd64.whl", hash = "sha256:a4fa6f80816a9a0678429e84973f2f98cbc218cca434abe8db2ad0bffc98503a"}, + {file = "protobuf-5.29.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a8434404bbf139aa9e1300dbf989667a83d42ddda9153d8ab76e0d5dcaca484e"}, + {file = "protobuf-5.29.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:daaf63f70f25e8689c072cfad4334ca0ac1d1e05a92fc15c54eb9cf23c3efd84"}, + {file = "protobuf-5.29.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:c027e08a08be10b67c06bf2370b99c811c466398c357e615ca88c91c07f0910f"}, + {file = "protobuf-5.29.3-cp38-cp38-win32.whl", hash = "sha256:84a57163a0ccef3f96e4b6a20516cedcf5bb3a95a657131c5c3ac62200d23252"}, + {file = "protobuf-5.29.3-cp38-cp38-win_amd64.whl", hash = "sha256:b89c115d877892a512f79a8114564fb435943b59067615894c3b13cd3e1fa107"}, + {file = "protobuf-5.29.3-cp39-cp39-win32.whl", hash = "sha256:0eb32bfa5219fc8d4111803e9a690658aa2e6366384fd0851064b963b6d1f2a7"}, + {file = "protobuf-5.29.3-cp39-cp39-win_amd64.whl", hash = "sha256:6ce8cc3389a20693bfde6c6562e03474c40851b44975c9b2bf6df7d8c4f864da"}, + {file = "protobuf-5.29.3-py3-none-any.whl", hash = "sha256:0a18ed4a24198528f2333802eb075e59dea9d679ab7a6c5efb017a59004d849f"}, + {file = "protobuf-5.29.3.tar.gz", hash = "sha256:5da0f41edaf117bde316404bad1a486cb4ededf8e4a54891296f648e8e076620"}, ] [[package]] name = "psutil" -version = "6.0.0" +version = "6.1.1" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, - {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, - {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, - {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, - {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, - {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, - {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, - {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, - {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, - {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, + {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, + {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, + {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, + {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, + {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, + {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, + {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, + {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, ] [package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] [[package]] name = "pydantic" -version = "2.10.4" +version = "2.10.5" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.10.4-py3-none-any.whl", hash = "sha256:597e135ea68be3a37552fb524bc7d0d66dcf93d395acd93a00682f1efcb8ee3d"}, - {file = "pydantic-2.10.4.tar.gz", hash = "sha256:82f12e9723da6de4fe2ba888b5971157b3be7ad914267dea8f05f82b28254f06"}, + {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, + {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, ] [package.dependencies] @@ -1527,22 +1452,24 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.25.0" +version = "0.25.2" description = "Pytest support for asyncio" optional = false python-versions = ">=3.9" files = [ - {file = "pytest_asyncio-0.25.0-py3-none-any.whl", hash = "sha256:db5432d18eac6b7e28b46dcd9b69921b55c3b1086e85febfe04e70b18d9e81b3"}, - {file = "pytest_asyncio-0.25.0.tar.gz", hash = "sha256:8c0610303c9e0442a5db8604505fc0f545456ba1528824842b37b4a626cbf609"}, + {file = "pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075"}, + {file = "pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f"}, ] [package.dependencies] @@ -1796,121 +1723,26 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "safetensors" -version = "0.4.5" +version = "0.5.2" description = "" optional = false python-versions = ">=3.7" files = [ - {file = "safetensors-0.4.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a63eaccd22243c67e4f2b1c3e258b257effc4acd78f3b9d397edc8cf8f1298a7"}, - {file = "safetensors-0.4.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:23fc9b4ec7b602915cbb4ec1a7c1ad96d2743c322f20ab709e2c35d1b66dad27"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6885016f34bef80ea1085b7e99b3c1f92cb1be78a49839203060f67b40aee761"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:133620f443450429322f238fda74d512c4008621227fccf2f8cf4a76206fea7c"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3e0609ec12d2a77e882f07cced530b8262027f64b75d399f1504ffec0ba56"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d0f1dd769f064adc33831f5e97ad07babbd728427f98e3e1db6902e369122737"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6d156bdb26732feada84f9388a9f135528c1ef5b05fae153da365ad4319c4c5"}, - {file = "safetensors-0.4.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e347d77e2c77eb7624400ccd09bed69d35c0332f417ce8c048d404a096c593b"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9f556eea3aec1d3d955403159fe2123ddd68e880f83954ee9b4a3f2e15e716b6"}, - {file = "safetensors-0.4.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9483f42be3b6bc8ff77dd67302de8ae411c4db39f7224dec66b0eb95822e4163"}, - {file = "safetensors-0.4.5-cp310-none-win32.whl", hash = "sha256:7389129c03fadd1ccc37fd1ebbc773f2b031483b04700923c3511d2a939252cc"}, - {file = "safetensors-0.4.5-cp310-none-win_amd64.whl", hash = "sha256:e98ef5524f8b6620c8cdef97220c0b6a5c1cef69852fcd2f174bb96c2bb316b1"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:21f848d7aebd5954f92538552d6d75f7c1b4500f51664078b5b49720d180e47c"}, - {file = "safetensors-0.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb07000b19d41e35eecef9a454f31a8b4718a185293f0d0b1c4b61d6e4487971"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09dedf7c2fda934ee68143202acff6e9e8eb0ddeeb4cfc24182bef999efa9f42"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59b77e4b7a708988d84f26de3ebead61ef1659c73dcbc9946c18f3b1786d2688"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d3bc83e14d67adc2e9387e511097f254bd1b43c3020440e708858c684cbac68"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39371fc551c1072976073ab258c3119395294cf49cdc1f8476794627de3130df"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6c19feda32b931cae0acd42748a670bdf56bee6476a046af20181ad3fee4090"}, - {file = "safetensors-0.4.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a659467495de201e2f282063808a41170448c78bada1e62707b07a27b05e6943"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad5e4b2476949bcd638a89f71b6916fa9a5cae5c1ae7eede337aca2100435c0"}, - {file = "safetensors-0.4.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a3a315a6d0054bc6889a17f5668a73f94f7fe55121ff59e0a199e3519c08565f"}, - {file = "safetensors-0.4.5-cp311-none-win32.whl", hash = "sha256:a01e232e6d3d5cf8b1667bc3b657a77bdab73f0743c26c1d3c5dd7ce86bd3a92"}, - {file = "safetensors-0.4.5-cp311-none-win_amd64.whl", hash = "sha256:cbd39cae1ad3e3ef6f63a6f07296b080c951f24cec60188378e43d3713000c04"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:473300314e026bd1043cef391bb16a8689453363381561b8a3e443870937cc1e"}, - {file = "safetensors-0.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:801183a0f76dc647f51a2d9141ad341f9665602a7899a693207a82fb102cc53e"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1524b54246e422ad6fb6aea1ac71edeeb77666efa67230e1faf6999df9b2e27f"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3139098e3e8b2ad7afbca96d30ad29157b50c90861084e69fcb80dec7430461"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65573dc35be9059770808e276b017256fa30058802c29e1038eb1c00028502ea"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd33da8e9407559f8779c82a0448e2133737f922d71f884da27184549416bfed"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3685ce7ed036f916316b567152482b7e959dc754fcc4a8342333d222e05f407c"}, - {file = "safetensors-0.4.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dde2bf390d25f67908278d6f5d59e46211ef98e44108727084d4637ee70ab4f1"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7469d70d3de970b1698d47c11ebbf296a308702cbaae7fcb993944751cf985f4"}, - {file = "safetensors-0.4.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3a6ba28118636a130ccbb968bc33d4684c48678695dba2590169d5ab03a45646"}, - {file = "safetensors-0.4.5-cp312-none-win32.whl", hash = "sha256:c859c7ed90b0047f58ee27751c8e56951452ed36a67afee1b0a87847d065eec6"}, - {file = "safetensors-0.4.5-cp312-none-win_amd64.whl", hash = "sha256:b5a8810ad6a6f933fff6c276eae92c1da217b39b4d8b1bc1c0b8af2d270dc532"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:25e5f8e2e92a74f05b4ca55686234c32aac19927903792b30ee6d7bd5653d54e"}, - {file = "safetensors-0.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:81efb124b58af39fcd684254c645e35692fea81c51627259cdf6d67ff4458916"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:585f1703a518b437f5103aa9cf70e9bd437cb78eea9c51024329e4fb8a3e3679"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b99fbf72e3faf0b2f5f16e5e3458b93b7d0a83984fe8d5364c60aa169f2da89"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b17b299ca9966ca983ecda1c0791a3f07f9ca6ab5ded8ef3d283fff45f6bcd5f"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76ded72f69209c9780fdb23ea89e56d35c54ae6abcdec67ccb22af8e696e449a"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2783956926303dcfeb1de91a4d1204cd4089ab441e622e7caee0642281109db3"}, - {file = "safetensors-0.4.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d94581aab8c6b204def4d7320f07534d6ee34cd4855688004a4354e63b639a35"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:67e1e7cb8678bb1b37ac48ec0df04faf689e2f4e9e81e566b5c63d9f23748523"}, - {file = "safetensors-0.4.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:dbd280b07e6054ea68b0cb4b16ad9703e7d63cd6890f577cb98acc5354780142"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:77d9b228da8374c7262046a36c1f656ba32a93df6cc51cd4453af932011e77f1"}, - {file = "safetensors-0.4.5-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:500cac01d50b301ab7bb192353317035011c5ceeef0fca652f9f43c000bb7f8d"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75331c0c746f03158ded32465b7d0b0e24c5a22121743662a2393439c43a45cf"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:670e95fe34e0d591d0529e5e59fd9d3d72bc77b1444fcaa14dccda4f36b5a38b"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:098923e2574ff237c517d6e840acada8e5b311cb1fa226019105ed82e9c3b62f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ca0902d2648775089fa6a0c8fc9e6390c5f8ee576517d33f9261656f851e3f"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0032bedc869c56f8d26259fe39cd21c5199cd57f2228d817a0e23e8370af25"}, - {file = "safetensors-0.4.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f4b15f51b4f8f2a512341d9ce3475cacc19c5fdfc5db1f0e19449e75f95c7dc8"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f6594d130d0ad933d885c6a7b75c5183cb0e8450f799b80a39eae2b8508955eb"}, - {file = "safetensors-0.4.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:60c828a27e852ded2c85fc0f87bf1ec20e464c5cd4d56ff0e0711855cc2e17f8"}, - {file = "safetensors-0.4.5-cp37-none-win32.whl", hash = "sha256:6d3de65718b86c3eeaa8b73a9c3d123f9307a96bbd7be9698e21e76a56443af5"}, - {file = "safetensors-0.4.5-cp37-none-win_amd64.whl", hash = "sha256:5a2d68a523a4cefd791156a4174189a4114cf0bf9c50ceb89f261600f3b2b81a"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:e7a97058f96340850da0601a3309f3d29d6191b0702b2da201e54c6e3e44ccf0"}, - {file = "safetensors-0.4.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:63bfd425e25f5c733f572e2246e08a1c38bd6f2e027d3f7c87e2e43f228d1345"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3664ac565d0e809b0b929dae7ccd74e4d3273cd0c6d1220c6430035befb678e"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:313514b0b9b73ff4ddfb4edd71860696dbe3c1c9dc4d5cc13dbd74da283d2cbf"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31fa33ee326f750a2f2134a6174773c281d9a266ccd000bd4686d8021f1f3dac"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09566792588d77b68abe53754c9f1308fadd35c9f87be939e22c623eaacbed6b"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309aaec9b66cbf07ad3a2e5cb8a03205663324fea024ba391594423d0f00d9fe"}, - {file = "safetensors-0.4.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53946c5813b8f9e26103c5efff4a931cc45d874f45229edd68557ffb35ffb9f8"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:868f9df9e99ad1e7f38c52194063a982bc88fedc7d05096f4f8160403aaf4bd6"}, - {file = "safetensors-0.4.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9cc9449bd0b0bc538bd5e268221f0c5590bc5c14c1934a6ae359d44410dc68c4"}, - {file = "safetensors-0.4.5-cp38-none-win32.whl", hash = "sha256:83c4f13a9e687335c3928f615cd63a37e3f8ef072a3f2a0599fa09f863fb06a2"}, - {file = "safetensors-0.4.5-cp38-none-win_amd64.whl", hash = "sha256:b98d40a2ffa560653f6274e15b27b3544e8e3713a44627ce268f419f35c49478"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:cf727bb1281d66699bef5683b04d98c894a2803442c490a8d45cd365abfbdeb2"}, - {file = "safetensors-0.4.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96f1d038c827cdc552d97e71f522e1049fef0542be575421f7684756a748e457"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:139fbee92570ecea774e6344fee908907db79646d00b12c535f66bc78bd5ea2c"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c36302c1c69eebb383775a89645a32b9d266878fab619819ce660309d6176c9b"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d641f5b8149ea98deb5ffcf604d764aad1de38a8285f86771ce1abf8e74c4891"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b4db6a61d968de73722b858038c616a1bebd4a86abe2688e46ca0cc2d17558f2"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b75a616e02f21b6f1d5785b20cecbab5e2bd3f6358a90e8925b813d557666ec1"}, - {file = "safetensors-0.4.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:788ee7d04cc0e0e7f944c52ff05f52a4415b312f5efd2ee66389fb7685ee030c"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87bc42bd04fd9ca31396d3ca0433db0be1411b6b53ac5a32b7845a85d01ffc2e"}, - {file = "safetensors-0.4.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4037676c86365a721a8c9510323a51861d703b399b78a6b4486a54a65a975fca"}, - {file = "safetensors-0.4.5-cp39-none-win32.whl", hash = "sha256:1500418454529d0ed5c1564bda376c4ddff43f30fce9517d9bee7bcce5a8ef50"}, - {file = "safetensors-0.4.5-cp39-none-win_amd64.whl", hash = "sha256:9d1a94b9d793ed8fe35ab6d5cea28d540a46559bafc6aae98f30ee0867000cab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fdadf66b5a22ceb645d5435a0be7a0292ce59648ca1d46b352f13cff3ea80410"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d42ffd4c2259f31832cb17ff866c111684c87bd930892a1ba53fed28370c918c"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd8a1f6d2063a92cd04145c7fd9e31a1c7d85fbec20113a14b487563fdbc0597"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:951d2fcf1817f4fb0ef0b48f6696688a4e852a95922a042b3f96aaa67eedc920"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ac85d9a8c1af0e3132371d9f2d134695a06a96993c2e2f0bbe25debb9e3f67a"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e3cec4a29eb7fe8da0b1c7988bc3828183080439dd559f720414450de076fcab"}, - {file = "safetensors-0.4.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:21742b391b859e67b26c0b2ac37f52c9c0944a879a25ad2f9f9f3cd61e7fda8f"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7db3006a4915151ce1913652e907cdede299b974641a83fbc092102ac41b644"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f68bf99ea970960a237f416ea394e266e0361895753df06e3e06e6ea7907d98b"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8158938cf3324172df024da511839d373c40fbfaa83e9abf467174b2910d7b4c"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:540ce6c4bf6b58cb0fd93fa5f143bc0ee341c93bb4f9287ccd92cf898cc1b0dd"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bfeaa1a699c6b9ed514bd15e6a91e74738b71125a9292159e3d6b7f0a53d2cde"}, - {file = "safetensors-0.4.5-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:01c8f00da537af711979e1b42a69a8ec9e1d7112f208e0e9b8a35d2c381085ef"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a0dd565f83b30f2ca79b5d35748d0d99dd4b3454f80e03dfb41f0038e3bdf180"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:023b6e5facda76989f4cba95a861b7e656b87e225f61811065d5c501f78cdb3f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9633b663393d5796f0b60249549371e392b75a0b955c07e9c6f8708a87fc841f"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78dd8adfb48716233c45f676d6e48534d34b4bceb50162c13d1f0bdf6f78590a"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8e8deb16c4321d61ae72533b8451ec4a9af8656d1c61ff81aa49f966406e4b68"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:52452fa5999dc50c4decaf0c53aa28371f7f1e0fe5c2dd9129059fbe1e1599c7"}, - {file = "safetensors-0.4.5-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d5f23198821e227cfc52d50fa989813513db381255c6d100927b012f0cfec63d"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f4beb84b6073b1247a773141a6331117e35d07134b3bb0383003f39971d414bb"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:68814d599d25ed2fdd045ed54d370d1d03cf35e02dce56de44c651f828fb9b7b"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b6453c54c57c1781292c46593f8a37254b8b99004c68d6c3ce229688931a22"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adaa9c6dead67e2dd90d634f89131e43162012479d86e25618e821a03d1eb1dc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73e7d408e9012cd17511b382b43547850969c7979efc2bc353f317abaf23c84c"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:775409ce0fcc58b10773fdb4221ed1eb007de10fe7adbdf8f5e8a56096b6f0bc"}, - {file = "safetensors-0.4.5-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:834001bed193e4440c4a3950a31059523ee5090605c907c66808664c932b549c"}, - {file = "safetensors-0.4.5.tar.gz", hash = "sha256:d73de19682deabb02524b3d5d1f8b3aaba94c72f1bbfc7911b9b9d5d391c0310"}, + {file = "safetensors-0.5.2-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:45b6092997ceb8aa3801693781a71a99909ab9cc776fbc3fa9322d29b1d3bef2"}, + {file = "safetensors-0.5.2-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6d0d6a8ee2215a440e1296b843edf44fd377b055ba350eaba74655a2fe2c4bae"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:86016d40bcaa3bcc9a56cd74d97e654b5f4f4abe42b038c71e4f00a089c4526c"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:990833f70a5f9c7d3fc82c94507f03179930ff7d00941c287f73b6fcbf67f19e"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dfa7c2f3fe55db34eba90c29df94bcdac4821043fc391cb5d082d9922013869"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46ff2116150ae70a4e9c490d2ab6b6e1b1b93f25e520e540abe1b81b48560c3a"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab696dfdc060caffb61dbe4066b86419107a24c804a4e373ba59be699ebd8d5"}, + {file = "safetensors-0.5.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:03c937100f38c9ff4c1507abea9928a6a9b02c9c1c9c3609ed4fb2bf413d4975"}, + {file = "safetensors-0.5.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a00e737948791b94dad83cf0eafc09a02c4d8c2171a239e8c8572fe04e25960e"}, + {file = "safetensors-0.5.2-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:d3a06fae62418ec8e5c635b61a8086032c9e281f16c63c3af46a6efbab33156f"}, + {file = "safetensors-0.5.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:1506e4c2eda1431099cebe9abf6c76853e95d0b7a95addceaa74c6019c65d8cf"}, + {file = "safetensors-0.5.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5c5b5d9da594f638a259fca766046f44c97244cc7ab8bef161b3e80d04becc76"}, + {file = "safetensors-0.5.2-cp38-abi3-win32.whl", hash = "sha256:fe55c039d97090d1f85277d402954dd6ad27f63034fa81985a9cc59655ac3ee2"}, + {file = "safetensors-0.5.2-cp38-abi3-win_amd64.whl", hash = "sha256:78abdddd03a406646107f973c7843276e7b64e5e32623529dc17f3d94a20f589"}, + {file = "safetensors-0.5.2.tar.gz", hash = "sha256:cb4a8d98ba12fa016f4241932b1fc5e702e5143f5374bba0bbcf7ddc1c4cf2b8"}, ] [package.extras] @@ -1920,7 +1752,7 @@ jax = ["flax (>=0.6.3)", "jax (>=0.3.25)", "jaxlib (>=0.3.25)", "safetensors[num mlx = ["mlx (>=0.0.9)"] numpy = ["numpy (>=1.21.6)"] paddlepaddle = ["paddlepaddle (>=2.4.1)", "safetensors[numpy]"] -pinned-tf = ["safetensors[numpy]", "tensorflow (==2.11.0)"] +pinned-tf = ["safetensors[numpy]", "tensorflow (==2.18.0)"] quality = ["black (==22.3)", "click (==8.0.4)", "flake8 (>=3.8.3)", "isort (>=5.5.4)"] tensorflow = ["safetensors[numpy]", "tensorflow (>=2.11.0)"] testing = ["h5py (>=3.7.0)", "huggingface-hub (>=0.12.1)", "hypothesis (>=6.70.2)", "pytest (>=7.2.0)", "pytest-benchmark (>=4.0.0)", "safetensors[numpy]", "setuptools-rust (>=1.5.2)"] @@ -1928,23 +1760,23 @@ torch = ["safetensors[numpy]", "torch (>=1.10)"] [[package]] name = "setuptools" -version = "75.6.0" +version = "75.8.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" files = [ - {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, - {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, + {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, + {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, ] [package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.8.0)"] core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] -test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] -type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (==1.14.*)", "pytest-mypy"] [[package]] name = "six" @@ -2034,6 +1866,47 @@ dev = ["tokenizers[testing]"] docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"] testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"] +[[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 = "torch" version = "2.4.1" @@ -2241,13 +2114,13 @@ devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3) [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.extras] @@ -2270,6 +2143,7 @@ files = [ [package.dependencies] click = ">=7.0" h11 = ">=0.8" +typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} [package.extras] standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] @@ -2386,5 +2260,5 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" -python-versions = "^3.12" -content-hash = "2268c8352cd9ac4018a5cb0d8396a91d358dddc9fc5807cb27bd41608b08b81e" +python-versions = "^3.10" +content-hash = "b8e46140dfec3638e577f0e40f6f46dfc35d46390fb63e7ac687323009f2dbce" diff --git a/model_server/pyproject.toml b/model_server/pyproject.toml index 351fb482..63c5a045 100644 --- a/model_server/pyproject.toml +++ b/model_server/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "archgw_modelserver" -version = "0.1.7" +version = "0.1.8" description = "A model server for serving models" authors = ["Katanemo Labs, Inc "] license = "Apache 2.0" @@ -10,17 +10,15 @@ packages = [ ] [tool.poetry.dependencies] -python = "^3.12" +python = "^3.10" fastapi = "0.115.0" torch = "2.4.1" uvicorn = "0.31.0" -transformers = "*" -pyyaml = "6.0.2" -accelerate = "*" -psutil = "6.0.0" -pandas = "*" +transformers = "^4.37.0" +accelerate = "^1.0.0" +pydantic = "^2.10.1" dateparser = "*" -openai = "1.50.2" +openai = "^1.50.2" httpx = "0.27.2" # https://community.openai.com/t/typeerror-asyncclient-init-got-an-unexpected-keyword-argument-proxies/1040287 pytest-asyncio = "*" pytest = "*" @@ -33,7 +31,7 @@ pytest-retry = "^1.6.3" pytest-httpserver = "^1.1.0" [tool.poetry.scripts] -archgw_modelserver = "src.cli:run_server" +archgw_modelserver = "src.cli:main" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/model_server/src/cli.py b/model_server/src/cli.py index 89fd82c0..5245873e 100644 --- a/model_server/src/cli.py +++ b/model_server/src/cli.py @@ -1,22 +1,17 @@ import importlib -import logging -from os import path import os -from signal import SIGKILL import sys import subprocess import argparse +import signal import tempfile import time - import requests -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", -) +import src.commons.utils as utils -logger = logging.getLogger(__name__) + +logger = utils.get_model_server_logger() def get_version(): @@ -42,76 +37,9 @@ def wait_for_health_check(url, timeout=300): return False -def parse_args(): - parser = argparse.ArgumentParser(description="Manage the Uvicorn server.") - parser.add_argument( - "action", - choices=["start", "stop", "restart"], - default="start", - nargs="?", - help="Action to perform on the server (default: start).", - ) - parser.add_argument( - "--port", - type=int, - default=51000, - help="Port number for the server (default: 51000).", - ) - - parser.add_argument( - "--foreground", - default=False, - action="store_true", - help="Run the server in the foreground (default: False).", - ) - - return parser.parse_args() - - def get_pid_file(): temp_dir = tempfile.gettempdir() - return path.join(temp_dir, "model_server.pid") - - -def stop_server(): - """Stop the Uvicorn server.""" - pid_file = get_pid_file() - if os.path.exists(pid_file): - logger.info(f"PID file found, shutting down the server.") - # read pid from file - with open(pid_file, "r") as f: - pid = int(f.read()) - logger.info(f"Killing model server {pid}") - try: - os.kill(pid, SIGKILL) - except ProcessLookupError: - logger.info(f"Process {pid} not found") - os.remove(pid_file) - else: - logger.info("No PID file found, server is not running.") - - -def restart_server(port=51000, foreground=False): - """Restart the Uvicorn server.""" - stop_server() - start_server(port, foreground) - - -def run_server(): - """Start, stop, or restart the Uvicorn server based on command-line arguments.""" - - args = parse_args() - action = args.action - - if action == "start": - start_server(args.port, args.foreground) - elif action == "stop": - stop_server() - elif action == "restart": - restart_server(args.port, args.foreground) - else: - logger.info(f"Unknown action: {action}") - sys.exit(1) + return os.path.join(temp_dir, "model_server.pid") def ensure_killed(process): @@ -131,7 +59,7 @@ def ensure_killed(process): def start_server(port=51000, foreground=False): """Start the Uvicorn server.""" - logging.info("model server version: %s", get_version()) + logger.info("model server version: %s", get_version()) stop_server() @@ -196,6 +124,57 @@ def start_server(port=51000, foreground=False): ensure_killed(process) +def stop_server(): + """Stop the Uvicorn server.""" + + pid_file = get_pid_file() + if os.path.exists(pid_file): + logger.info("PID file found, shutting down the server.") + # read pid from file + with open(pid_file, "r") as f: + pid = int(f.read()) + logger.info(f"Killing model server {pid}") + try: + os.kill(pid, signal.SIGKILL) + except ProcessLookupError: + logger.info(f"Process {pid} not found") + os.remove(pid_file) + else: + logger.info("No PID file found, server is not running.") + + +def restart_server(port=51000, foreground=False): + """Restart the Uvicorn server.""" + stop_server() + start_server(port, foreground) + + +def parse_args(): + parser = argparse.ArgumentParser(description="Manage the Uvicorn server.") + parser.add_argument( + "action", + choices=["start", "stop", "restart"], + default="start", + nargs="?", + help="Action to perform on the server (default: start).", + ) + parser.add_argument( + "--port", + type=int, + default=51000, + help="Port number for the server (default: 51000).", + ) + + parser.add_argument( + "--foreground", + default=False, + action="store_true", + help="Run the server in the foreground (default: False).", + ) + + return parser.parse_args() + + def main(): """ Start, stop, or restart the Uvicorn server based on command-line arguments. @@ -204,11 +183,14 @@ def main(): args = parse_args() if args.action == "start": + logger.info("[CLI] - Starting server") start_server(args.port, args.foreground) elif args.action == "stop": + logger.info("[CLI] - Stopping server") stop_server() elif args.action == "restart": + logger.info("[CLI] - Restarting server") restart_server(args.port) else: - logger.error(f"Unknown action: {args.action}") + logger.error(f"[CLI] - Unknown action: {args.action}") sys.exit(1) diff --git a/model_server/src/commons/globals.py b/model_server/src/commons/globals.py index 46ac1fef..68c2e53a 100644 --- a/model_server/src/commons/globals.py +++ b/model_server/src/commons/globals.py @@ -22,9 +22,7 @@ ARCH_CLIENT = OpenAI(base_url=ARCH_ENDPOINT, api_key=ARCH_API_KEY) # Define model names ARCH_INTENT_MODEL_ALIAS = "Arch-Intent" ARCH_FUNCTION_MODEL_ALIAS = "Arch-Function" - -logger.info("loading prompt guard model ...") -arch_guard_model = get_guardrail_handler() +ARCH_GUARD_MODEL_ALIAS = "katanemo/Arch-Guard" # Define model handlers handler_map = { @@ -34,5 +32,5 @@ handler_map = { "Arch-Function": ArchFunctionHandler( ARCH_CLIENT, ARCH_FUNCTION_MODEL_ALIAS, ArchFunctionConfig ), - "Arch-Guard": arch_guard_model, + "Arch-Guard": get_guardrail_handler(ARCH_GUARD_MODEL_ALIAS), } diff --git a/model_server/src/commons/utils.py b/model_server/src/commons/utils.py index fff7911d..76e46d13 100644 --- a/model_server/src/commons/utils.py +++ b/model_server/src/commons/utils.py @@ -1,87 +1,50 @@ -import os -import sys -import time +import torch import logging -import requests -import subprocess -import importlib + +from datetime import datetime -PROJ_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) - - -# Default log directory and file -DEFAULT_LOG_DIR = os.path.join(PROJ_DIR, ".logs") -DEFAULT_LOG_FILE = "modelserver.log" - - -def get_model_server_logger(log_dir=None, log_file=None): +def get_model_server_logger(): """ Get or initialize the logger instance for the model server. - Parameters: - - log_dir (str): Custom directory to store the log file. Defaults to `./.logs`. - - log_file (str): Custom log file name. Defaults to `modelserver.log`. - Returns: - logging.Logger: Configured logger instance. """ - log_dir = log_dir or DEFAULT_LOG_DIR - log_file = log_file or DEFAULT_LOG_FILE - log_file_path = os.path.join(log_dir, log_file) # Check if the logger is already configured - logger = logging.getLogger("model_server_logger") + logger = logging.getLogger("model_server") + + # Return existing logger instance if already configured if logger.hasHandlers(): - # Return existing logger instance if already configured return logger - # Ensure the log directory exists, create it if necessary - try: - # Create directory if it doesn't exist - os.makedirs(log_dir, exist_ok=True) - - # Check for write permissions - if not os.access(log_dir, os.W_OK): - raise PermissionError(f"No write permission for the directory: {log_dir}") - except (PermissionError, OSError) as e: - raise RuntimeError(f"Failed to initialize logger: {e}") - - # Configure logging to file + # Configure logging to only log to console logging.basicConfig( level=logging.INFO, - format="%(asctime)s - %(levelname)s - %(message)s", - handlers=[ - # logging.FileHandler(log_file_path, mode="w"), # Overwrite logs in the file - logging.StreamHandler(), # Also log to console - ], + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + handlers=[logging.StreamHandler()], ) return logger -logger = get_model_server_logger() - -logging.info("initializing torch device ...") -import torch - - def get_device(): - available_device = { - "cpu": True, - "cuda": torch.cuda.is_available(), - "mps": ( - torch.backends.mps.is_available() - if hasattr(torch.backends, "mps") - else False - ), - } - - if available_device["cuda"]: + if torch.cuda.is_available(): device = "cuda" - elif available_device["mps"]: + elif torch.backends.mps.is_available(): device = "mps" else: device = "cpu" return device + + +def get_today_date(): + # Get today's date + today = datetime.now() + + # Get full date with day of week + full_date = today.strftime("%Y-%m-%d") + + return full_date diff --git a/model_server/src/core/function_calling.py b/model_server/src/core/function_calling.py index e29dd3f1..25c83818 100644 --- a/model_server/src/core/function_calling.py +++ b/model_server/src/core/function_calling.py @@ -1,22 +1,24 @@ +import ast import json import random import builtins import textwrap +import src.commons.utils as utils from openai import OpenAI from typing import Any, Dict, List from overrides import override -from src.commons.utils import get_model_server_logger -from src.core.model_utils import ( +from src.core.utils.hallucination_utils import HallucinationState +from src.core.utils.model_utils import ( Message, ChatMessage, Choice, ChatCompletionResponse, ArchBaseHandler, ) -from src.core.hallucination import HallucinationStateHandler -logger = get_model_server_logger() + +logger = utils.get_model_server_logger() class ArchIntentConfig: @@ -74,7 +76,6 @@ class ArchIntentHandler(ArchBaseHandler): ) self.extra_instruction = config.EXTRA_INSTRUCTION - self.prompt_prefilling = False @override def _convert_tools(self, tools: List[Dict[str, Any]]) -> str: @@ -122,15 +123,19 @@ class ArchIntentHandler(ArchBaseHandler): Note: Currently only support vllm inference """ + logger.info("[Arch-Intent] - ChatCompletion") # In the case that no tools are available, simply return `No` to avoid making a call if len(req.tools) == 0: model_response = Message(content="No", tool_calls=[]) + logger.info("No tools found, return `No` as the model response.") else: messages = self._process_messages( req.messages, req.tools, self.extra_instruction ) + logger.info(f"[request]: {json.dumps(messages)}") + model_response = self.client.chat.completions.create( messages=messages, model=self.model_name, @@ -138,9 +143,7 @@ class ArchIntentHandler(ArchBaseHandler): extra_body=self.generation_params, ) - logger.info( - "arch_intent response: %s", json.dumps(model_response.model_dump()) - ) + logger.info(f"[response]: {json.dumps(model_response.model_dump())}") model_response = Message( content=model_response.choices[0].message.content, tool_calls=[] @@ -160,7 +163,11 @@ class ArchFunctionConfig: TASK_PROMPT = textwrap.dedent( """ You are a helpful assistant. - """ + + Today's date: {} + """.format( + utils.get_today_date() + ) ).strip() TOOL_PROMPT_TEMPLATE = textwrap.dedent( @@ -189,7 +196,7 @@ class ArchFunctionConfig: "temperature": 0.6, "top_p": 1.0, "top_k": 10, - "max_tokens": 512, + "max_tokens": 1024, "stop_token_ids": [151645], "logprobs": True, "top_logprobs": 10, @@ -241,10 +248,11 @@ class ArchFunctionHandler(ArchBaseHandler): self.prefill_params = config.PREFILL_CONFIG["prefill_params"] self.prefill_prefix = config.PREFILL_CONFIG["prefill_prefix"] - self.prompt_prefilling = False + + self.hallucination_state = None # Predefine data types for verification. Only support Python for now. - # [TODO] Extend the list of support data types + # TODO: Extend the list of support data types self.support_data_types = { type_name: getattr(builtins, type_name) for type_name in config.SUPPORT_DATA_TYPES @@ -365,15 +373,15 @@ class ArchFunctionHandler(ArchBaseHandler): return {"result": tool_calls, "status": is_valid, "message": error_message} - def _correcting_type(self, value, target_type): + def _convert_data_type(self, value: str, target_type: str): + # TODO: Add more conversion rules as needed try: - if target_type == float and isinstance(value, int): + if target_type is float and isinstance(value, int): return float(value) - elif target_type == list and isinstance(value, str): + elif target_type is list and isinstance(value, str): return ast.literal_eval(value) - elif target_type == str and not isinstance(value, str): + elif target_type is str and not isinstance(value, str): return str(value) - # Add more conversion rules as needed except (ValueError, TypeError, json.JSONDecodeError): pass return value @@ -426,32 +434,34 @@ class ArchFunctionHandler(ArchBaseHandler): break # Verify the data type of each parameter in the tool calls + function_properties = functions[func_name]["properties"] + for param_name in func_args: - if param_name not in functions[func_name]["properties"]: + if param_name not in function_properties: is_valid = False invalid_tool_call = tool_call error_message = f"Parameter `{param_name}` is not defined in the function `{func_name}`." break else: param_value = func_args[param_name] - data_type = functions[func_name]["properties"][param_name][ - "type" - ] + target_type = function_properties[param_name]["type"] - if data_type in self.support_data_types: - if not isinstance( - param_value, - self.support_data_types[data_type], - ) and not isinstance( - self._correcting_type( - param_value, self.support_data_types[data_type] - ), - self.support_data_types[data_type], - ): - is_valid = False - invalid_tool_call = tool_call - error_message = f"Parameter `{param_name}` is expected to have the data type `{self.support_data_types[data_type]}`, but got `{type(param_value)}`." - break + if target_type in self.support_data_types: + data_type = self.support_data_types[target_type] + + if not isinstance(param_value, data_type): + param_value = self._convert_data_type( + param_value, data_type + ) + if not isinstance(param_value, data_type): + is_valid = False + invalid_tool_call = tool_call + error_message = f"Parameter `{param_name}` is expected to have the data type `{data_type}`, got `{type(param_value)}`." + break + else: + error_message = ( + f"Data type `{target_type}` is not supported." + ) return { "status": is_valid, @@ -491,51 +501,8 @@ class ArchFunctionHandler(ArchBaseHandler): **self.prefill_params, }, ) - self.prompt_prefilling = True return prefill_response - def _check_length_and_pop_messages(self, messages, max_tokens=4096): - """ - Trims the `messages` list to ensure the total token count does not exceed `max_tokens`. - - Args: - messages (list): List of message dictionaries. - max_tokens (int): Maximum allowed token count. - - Returns: - list: Trimmed list of messages. - """ - - def estimate_token_length(messages): - """Estimate the total token length of the messages.""" - total_tokens = 0 - for message in messages: - # Approximate token length: assuming ~4 characters per token on average - total_tokens += len(message["content"]) // 4 - return total_tokens - - # Calculate initial token length - total_tokens = estimate_token_length(messages) - - # Trim messages if token count exceeds the limit - while total_tokens > max_tokens and len(messages) >= 3: - # Find the first non-system message pair - for i in range(len(messages)): - if messages[i]["role"] != "system": - # Remove the 'user'/'assistant' pair - if i + 1 < len(messages) and messages[i + 1]["role"] in [ - "user", - "assistant", - ]: - del messages[i : i + 2] - else: - del messages[i] - break - # Recalculate token length - total_tokens = estimate_token_length(messages) - - return messages - @override async def chat_completion(self, req: ChatMessage) -> ChatCompletionResponse: """ @@ -550,13 +517,11 @@ class ArchFunctionHandler(ArchBaseHandler): Note: Currently only support vllm inference """ - - logger.info( - f"model_server => arch_function: request body: {json.dumps(req.model_dump())}" - ) + logger.info("[Arch-Function] - ChatCompletion") messages = self._process_messages(req.messages, req.tools) - messages = self._check_length_and_pop_messages(messages) + + logger.info(f"[request]: {json.dumps(messages)}") # always enable `stream=True` to collect model responses response = self.client.chat.completions.create( @@ -567,45 +532,39 @@ class ArchFunctionHandler(ArchBaseHandler): ) # initialize the hallucination handler, which is an iterator - self.hallu_handler = HallucinationStateHandler( + self.hallucination_state = HallucinationState( response_iterator=response, function=req.tools ) - model_response, self.has_tool_call = "", None - self.hallucination = False - for _ in self.hallu_handler: + model_response = "" + + has_tool_calls, has_hallucination = None, False + for _ in self.hallucination_state: # check if the first token is - if len(self.hallu_handler.tokens) > 0 and self.has_tool_call is None: - if self.hallu_handler.tokens[0] == "": - self.has_tool_call = True + if len(self.hallucination_state.tokens) > 0 and has_tool_calls is None: + if self.hallucination_state.tokens[0] == "": + has_tool_calls = True else: - self.has_tool_call = False + has_tool_calls = False break # if the model is hallucinating, start parameter gathering - if self.hallu_handler.hallucination is True: - self.hallucination = True - logger.info( - f"{self.hallu_handler.error_message} - start parameter gathering" - ) - logger.info( - f"Hallucinated response : {''.join(self.hallu_handler.tokens)}" - ) - # [TODO] - add break when hallucination is detected + if self.hallucination_state.hallucination is True: + has_hallucination = True break - if self.hallucination is True: - prefill_response = self._engage_parameter_gathering(messages) - model_response = prefill_response.choices[0].message.content - if self.has_tool_call and self.hallucination is False: - # [TODO] - Review: remove the following code - - model_response = "".join(self.hallu_handler.tokens) - logger.info(f"Tool call found, no hallucination detected {model_response}!") - # start parameter gathering if the model is not generating tool calls - if self.has_tool_call is False: - # [TODO] - Review: remove the following code - logger.info("No tool call found, start parameter gathering") + if has_tool_calls: + if has_hallucination: + # start prompt prefilling if hallcuination is found in tool calls + logger.info( + f"[Hallucination]: {self.hallucination_state.error_message}" + ) + prefill_response = self._engage_parameter_gathering(messages) + model_response = prefill_response.choices[0].message.content + else: + model_response = "".join(self.hallucination_state.tokens) + else: + # start parameter gathering if the model is not generating tool calls prefill_response = self._engage_parameter_gathering(messages) model_response = prefill_response.choices[0].message.content @@ -613,21 +572,20 @@ class ArchFunctionHandler(ArchBaseHandler): extracted = self._extract_tool_calls(model_response) if len(extracted["result"]) and extracted["status"]: - # [TODO] Review: define the behavior in the case that tool call extraction fails - # if not extracted["status"]: verified = self._verify_tool_calls( tools=req.tools, tool_calls=extracted["result"] ) - # [TODO] - Review: remvoe the following code - # print(f"[Verified] - {verified}") - # [TODO] Review: In the case that tool calls are invalid, define the protocol to collect debugging output and the behavior to handle it appropriately if verified["status"]: + logger.info( + f"[Tool calls]: {json.dumps([tool_call['function'] for tool_call in extracted['result']])}" + ) model_response = Message(content="", tool_calls=extracted["result"]) - log_message = f"model_server <= arch_function: (tool_calls): {json.dumps([tool_call['function'] for tool_call in extracted['result']])}" - logger.info(log_message) else: - raise ValueError(f"Invalid tool call: {verified['message']}") + logger.error(f"Invalid tool call - {verified['message']}") + # raise ValueError( + # f"[Arch-Function]: Invalid tool call - {verified['message']}" + # ) else: model_response = Message(content=model_response, tool_calls=[]) @@ -635,10 +593,6 @@ class ArchFunctionHandler(ArchBaseHandler): choices=[Choice(message=model_response)], model=self.model_name ) - # [TODO] Review: define the protocol to collect debugging output - - logger.info( - f"model_server <= arch_function: response body: {json.dumps(chat_completion_response.model_dump())}" - ) + logger.info(f"[response]: {json.dumps(chat_completion_response.model_dump())}") return chat_completion_response diff --git a/model_server/src/core/guardrails.py b/model_server/src/core/guardrails.py index 33fe38f7..0d2f34fc 100644 --- a/model_server/src/core/guardrails.py +++ b/model_server/src/core/guardrails.py @@ -1,12 +1,12 @@ -import time import torch import numpy as np import src.commons.utils as utils -from transformers import AutoTokenizer -from src.core.model_utils import GuardRequest, GuardResponse -# from optimum.intel import OVModelForSequenceClassification -from transformers import AutoModelForSequenceClassification +from transformers import AutoTokenizer, AutoModelForSequenceClassification +from src.core.utils.model_utils import GuardRequest, GuardResponse + + +logger = utils.get_model_server_logger() class ArchGuardHanlder: @@ -76,26 +76,15 @@ class ArchGuardHanlder: text, truncation=True, max_length=max_length, return_tensors="pt" ).to(self.device) - start_time = time.perf_counter() - with torch.no_grad(): logits = self.model(**inputs).logits.cpu().detach().numpy()[0] prob = ArchGuardHanlder.softmax(logits)[ self.support_tasks[task]["positive_class"] - ] + ].item() - latency = time.perf_counter() - start_time + verdict = prob > self.support_tasks[task]["threshold"] - if prob > self.support_tasks[task]["threshold"]: - verdict = True - sentence = text - else: - verdict = False - sentence = None - - return GuardResponse( - prob=[prob.item()], verdict=verdict, sentence=[sentence], latency=latency - ) + return GuardResponse(task=task, input=text, prob=prob, verdict=verdict) def predict(self, req: GuardRequest, max_num_words=300) -> GuardResponse: """ @@ -115,29 +104,37 @@ class ArchGuardHanlder: if req.task not in self.support_tasks: raise NotImplementedError(f"{req.task} is not supported!") + logger.info("[Arch-Guard] - Prediction") + logger.info(f"[request]: {req.input}") + if len(req.input.split()) < max_num_words: - return self._predict_text(req.task, req.input) + result = self._predict_text(req.task, req.input) else: + prob, verdict = 0.0, False + # split into chunks if text is long text_chunks = self._split_text_into_chunks(req.input) - prob, verdict, sentence, latency = [], False, [], 0 - for chunk in text_chunks: chunk_result = self._predict_text(req.task, chunk) if chunk_result.verdict: - prob.append(chunk_result.prob[0]) + prob = chunk_result.prob verdict = True - sentence.append(chunk_result.sentence[0]) - latency += chunk_result.latency + break - return GuardResponse( - prob=prob, verdict=verdict, sentence=sentence, latency=latency + result = GuardResponse( + task=req.task, input=req.input, prob=prob, verdict=verdict ) + logger.info( + f"[response]: {req.task}: {'True' if result.verdict else 'False'} (prob: {result.prob:.2f})" + ) -def get_guardrail_handler(device: str = None): + return result + + +def get_guardrail_handler(model_name: str = "katanemo/Arch-Guard", device: str = None): """ Initializes and returns an instance of ArchGuardHanlder based on the specified device. @@ -151,19 +148,11 @@ def get_guardrail_handler(device: str = None): if device is None: device = utils.get_device() - model_class, model_name = None, None - # if device == "cpu": - # model_class = OVModelForSequenceClassification - # model_name = "katanemo/Arch-Guard-cpu" - # else: - model_class = AutoModelForSequenceClassification - model_name = "katanemo/Arch-Guard" - guardrail_dict = { "device": device, "model_name": model_name, "tokenizer": AutoTokenizer.from_pretrained(model_name, trust_remote_code=True), - "model": model_class.from_pretrained( + "model": AutoModelForSequenceClassification.from_pretrained( model_name, device_map=device, low_cpu_mem_usage=True ), } diff --git a/model_server/src/core/utils/__init__.py b/model_server/src/core/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/model_server/src/core/hallucination.py b/model_server/src/core/utils/hallucination_utils.py similarity index 97% rename from model_server/src/core/hallucination.py rename to model_server/src/core/utils/hallucination_utils.py index a7b32e73..50006224 100644 --- a/model_server/src/core/hallucination.py +++ b/model_server/src/core/utils/hallucination_utils.py @@ -127,7 +127,7 @@ def is_parameter_property( return property_name in parameter_info -class HallucinationStateHandler: +class HallucinationState: """ A class to handle the state of hallucination detection in token processing. @@ -145,7 +145,7 @@ class HallucinationStateHandler: def __init__(self, response_iterator=None, function=None): """ - Initializes the HallucinationStateHandler with default values. + Initializes the HallucinationState with default values. """ self.tokens: List[str] = [] self.logprobs: List[float] = [] @@ -173,7 +173,7 @@ class HallucinationStateHandler: def _reset_parameters(self): """ - Resets all parameters in the HallucinationStateHandler to their default values. + Resets all parameters in the HallucinationState to their default values. """ self.state = None self.parameter_name_done = False @@ -268,7 +268,7 @@ class HallucinationStateHandler: # if the parameter name is done and the token is a parameter name start token, change the state elif ( self.parameter_name_done - and self.open_bracket == False + and not self.open_bracket and content.endswith(PARAMETER_NAME_START_PATTERN) ): self.state = "parameter_name" @@ -324,7 +324,7 @@ class HallucinationStateHandler: # if the state is parameter value and the token is an end token, change the state elif ( self.state == "parameter_value" - and self.open_bracket == False + and not self.open_bracket and content.endswith(PARAMETER_VALUE_END_TOKEN) ): self.state = None @@ -354,7 +354,7 @@ class HallucinationStateHandler: self.HALLUCINATION_THRESHOLD_DICT[self.mask[-1].value], ): self.hallucination = True - self.error_message = f"Hallucination: token '{self.tokens[-1]}' is uncertain. {self.token_probs_map}" + self.error_message = f"token '{self.tokens[-1]}' is uncertain. Generated response:\n{''.join(self.tokens)}" def _count_consecutive_token(self, token=MaskToken.PARAMETER_VALUE) -> int: """ diff --git a/model_server/src/core/model_utils.py b/model_server/src/core/utils/model_utils.py similarity index 77% rename from model_server/src/core/model_utils.py rename to model_server/src/core/utils/model_utils.py index 3f6b36b0..d971d115 100644 --- a/model_server/src/core/model_utils.py +++ b/model_server/src/core/utils/model_utils.py @@ -14,8 +14,8 @@ class Message(BaseModel): class ChatMessage(BaseModel): - messages: list[Message] - tools: List[Dict[str, Any]] + messages: List[Message] = [] + tools: List[Dict[str, Any]] = [] class Choice(BaseModel): @@ -28,8 +28,8 @@ class ChatCompletionResponse(BaseModel): id: Optional[int] = 0 object: Optional[str] = "chat_completion" created: Optional[str] = "" - choices: List[Choice] - model: str + choices: List[Choice] = [] + model: str = "" metadata: Optional[Dict[str, str]] = {} @@ -39,10 +39,11 @@ class GuardRequest(BaseModel): class GuardResponse(BaseModel): - prob: List - verdict: bool - sentence: List - latency: float = 0 + task: str = "" + input: str = "" + prob: float = 0.0 + verdict: bool = False + metadata: Optional[Dict[str, str]] = {} # ================================================================================================ @@ -121,6 +122,7 @@ class ArchBaseHandler: messages: List[Message], tools: List[Dict[str, Any]] = None, extra_instruction: str = None, + max_tokens=4096, ): """ Processes a list of messages and formats them appropriately. @@ -129,6 +131,7 @@ class ArchBaseHandler: messages (List[Message]): A list of message objects. tools (List[Dict[str, Any]], optional): A list of tools to include in the system prompt. extra_instruction (str, optional): Additional instructions to append to the last user message. + max_tokens (int): Maximum allowed token count, assuming ~4 characters per token on average. Returns: List[Dict[str, Any]]: A list of processed message dictionaries. @@ -149,14 +152,12 @@ class ArchBaseHandler: ) if tool_calls: - # [TODO] Extend to support multiple function calls + # TODO: Extend to support multiple function calls role = "assistant" content = f"\n{json.dumps(tool_calls[0]['function'])}\n" - elif message.role == "tool": + elif role == "tool": role = "user" - content = ( - f"\n{json.dumps(message.content)}\n" - ) + content = f"\n{json.dumps(content)}\n" processed_messages.append({"role": role, "content": content}) @@ -165,6 +166,23 @@ class ArchBaseHandler: if extra_instruction: processed_messages[-1]["content"] += extra_instruction + # keep the first system message and shift conversation if the total token length exceeds the limit + def truncate_messages(messages: List[Dict[str, Any]]): + num_tokens, conversation_idx = 0, 0 + if messages[0]["role"] == "system": + num_tokens += len(messages[0]["content"]) // 4 + conversation_idx = 1 + + for message_idx in range(len(messages) - 1, conversation_idx - 1, -1): + num_tokens += len(messages[message_idx]["content"]) // 4 + if num_tokens >= max_tokens: + if messages[message_idx]["role"] == "user": + break + + return messages[:conversation_idx] + messages[message_idx:] + + processed_messages = truncate_messages(processed_messages) + return processed_messages async def chat_completion(self, req: ChatMessage) -> ChatCompletionResponse: diff --git a/model_server/src/main.py b/model_server/src/main.py index b09e635c..74f60011 100644 --- a/model_server/src/main.py +++ b/model_server/src/main.py @@ -1,25 +1,25 @@ import json -import logging import os import time +import logging +import src.commons.utils as utils from src.commons.globals import handler_map -from src.core.model_utils import ChatMessage, GuardRequest +from src.core.utils.model_utils import ( + ChatMessage, + ChatCompletionResponse, + GuardRequest, + GuardResponse, +) from fastapi import FastAPI, Response from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider -from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor -from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.sdk.resources import Resource +from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", -) - -logger = logging.getLogger(__name__) resource = Resource.create( { @@ -31,11 +31,6 @@ resource = Resource.create( trace.set_tracer_provider(TracerProvider(resource=resource)) tracer = trace.get_tracer(__name__) - -app = FastAPI() - -FastAPIInstrumentor().instrument_app(app) - # DEFAULT_OTLP_HOST = "http://localhost:4317" DEFAULT_OTLP_HOST = "none" @@ -47,6 +42,16 @@ otlp_exporter = OTLPSpanExporter( trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_exporter)) +logger = utils.get_model_server_logger() +logging.getLogger("httpx").setLevel(logging.ERROR) +logging.getLogger("opentelemetry.exporter.otlp.proto.grpc.exporter").setLevel( + logging.ERROR +) + +app = FastAPI() +FastAPIInstrumentor().instrument_app(app) + + @app.get("/healthz") async def healthz(): return {"status": "ok"} @@ -62,73 +67,78 @@ async def models(): @app.post("/function_calling") async def function_calling(req: ChatMessage, res: Response): + logger.info("[Endpoint: /function_calling]") + logger.info(f"[request body]: {json.dumps(req.model_dump())}") + + final_response: ChatCompletionResponse = None + error_messages = None + try: intent_start_time = time.perf_counter() intent_response = await handler_map["Arch-Intent"].chat_completion(req) intent_latency = time.perf_counter() - intent_start_time if handler_map["Arch-Intent"].detect_intent(intent_response): - # [TODO] measure agreement between intent detection and function calling + # TODO: measure agreement between intent detection and function calling try: function_start_time = time.perf_counter() - function_calling_response = await handler_map[ - "Arch-Function" - ].chat_completion(req) + final_response = await handler_map["Arch-Function"].chat_completion(req) function_latency = time.perf_counter() - function_start_time - function_calling_response.metadata = { + + final_response.metadata = { "intent_latency": str(round(intent_latency * 1000, 3)), "function_latency": str(round(function_latency * 1000, 3)), - "hallucination": str(handler_map["Arch-Function"].hallucination), - "tokens_uncertainty": json.dumps( - handler_map["Arch-Function"].hallu_handler.token_probs_map - ), - "prompt_prefilling": str( - handler_map["Arch-Function"].prompt_prefilling + "hallucination": str( + handler_map["Arch-Function"].hallucination_state.hallucination ), } - - return function_calling_response except ValueError as e: res.statuscode = 503 - error_message = "Tool call extraction error" - logger.error(f" {error_message}: {e}") - return {"error": f"[Arch-Function] - {error_message} - {e}"} + error_messages = f"[Arch-Function] - Error in tool call extraction: {e}" except StopIteration as e: res.statuscode = 500 - error_message = "Hallucination iterator error" - logger.error(f" {error_message}: {e}") - return {"error": f"[Arch-Function] - {error_message} - {e}"} + error_messages = f"[Arch-Function] - Error in hallucination check: {e}" except Exception as e: - # [TODO] Review: update how to collect debugging outputs - logger.error(f"Error in chat_completion from `Arch-Function`: {e}") res.status_code = 500 - return {"error": f"[Arch-Function] - {e}"} - # [TODO] Review: define the behavior if `Arch-Intent` doesn't detect an intent + error_messages = f"[Arch-Function] - Error in ChatCompletion: {e}" else: - return { - "result": "No intent matched", - "intent_latency": round(intent_latency * 1000, 3), + intent_response.metadata = { + "intent_latency": str(round(intent_latency * 1000, 3)), } + final_response = intent_response except Exception as e: - # [TODO] Review: update how to collect debugging outputs - # logger.error(f"Error in chat_completion from `Arch-Intent`: {e}") - logger.error(f"Error in chat_completion /function_calling: {e}") res.status_code = 500 - return {"error": f"[Arch-Intent] - {e}"} + error_messages = f"[Arch-Intent] - Error in ChatCompletion: {e}" + + if error_messages is not None: + logger.error(error_messages) + final_response = ChatCompletionResponse(metadata={"error": error_messages}) + + return final_response @app.post("/guardrails") async def guardrails(req: GuardRequest, res: Response, max_num_words=300): + logger.info("[Endpoint: /guardrails] - Gateway") + logger.info(f"[request body]: {json.dumps(req.model_dump())}") + + final_response: GuardResponse = None + error_messages = None + try: guard_start_time = time.perf_counter() - guard_result = handler_map["Arch-Guard"].predict(req) + final_response = handler_map["Arch-Guard"].predict(req) guard_latency = time.perf_counter() - guard_start_time - return { - "response": guard_result, + final_response.metadata = { "guard_latency": round(guard_latency * 1000, 3), } except Exception as e: - # [TODO] Review: update how to collect debugging outputs res.status_code = 500 - return {"error": f"[Arch-Guard] - {e}"} + error_messages = f"[Arch-Guard]: {e}" + + if error_messages is not None: + logger.error(error_messages) + final_response = GuardResponse(metadata={"error": error_messages}) + + return final_response diff --git a/model_server/tests/core/test_function_calling.py b/model_server/tests/core/test_function_calling.py index 1f213bba..3f7971d8 100644 --- a/model_server/tests/core/test_function_calling.py +++ b/model_server/tests/core/test_function_calling.py @@ -1,12 +1,8 @@ -import os +import pytest from src.commons.globals import handler_map -from src.core.model_utils import ChatMessage, Message -import pytest -from fastapi.testclient import TestClient -from unittest.mock import AsyncMock, patch -from src.main import app -from src.commons.globals import handler_map +from src.core.utils.model_utils import ChatMessage, Message + # define function get_weather_api = { @@ -163,7 +159,10 @@ async def test_function_calling(get_data_func): function_calling_response = await handler_map["Arch-Function"].chat_completion( req ) - assert handler_map["Arch-Function"].hallu_handler.hallucination == hallucination + assert ( + handler_map["Arch-Function"].hallucination_state.hallucination + == hallucination + ) response_txt = function_calling_response.choices[0].message.content if parameter_gathering: diff --git a/model_server/tests/core/test_guardrails.py b/model_server/tests/core/test_guardrails.py index e8d8ec81..74d2dc97 100644 --- a/model_server/tests/core/test_guardrails.py +++ b/model_server/tests/core/test_guardrails.py @@ -1,33 +1,6 @@ from unittest.mock import patch, MagicMock from src.core.guardrails import get_guardrail_handler -# Mock constants -arch_guard_model_type = { - "cpu": "katanemo/Arch-Guard-cpu", - "cuda": "katanemo/Arch-Guard", - "mps": "katanemo/Arch-Guard", -} - - -# [TODO] Review: check the following code to test under `cpu`, `cuda`, and `mps` -# Test for `get_guardrail_handler()` function on `cpu` -@patch("src.core.guardrails.AutoTokenizer.from_pretrained") -@patch("src.core.guardrails.AutoModelForSequenceClassification.from_pretrained") -def test_guardrail_handler_on_cpu(mock_auto_model, mock_tokenizer): - device = "cpu" - - mock_tokenizer.return_value = MagicMock() - - guardrail = get_guardrail_handler(device=device) - - mock_tokenizer.assert_called_once_with(guardrail.model_name, trust_remote_code=True) - - mock_auto_model.assert_called_once_with( - guardrail.model_name, - device_map=device, - low_cpu_mem_usage=True, - ) - # Test for `get_guardrail_handler()` function on `cuda` @patch("src.core.guardrails.AutoTokenizer.from_pretrained") diff --git a/model_server/tests/test_app.py b/model_server/tests/test_app.py index 39d377f4..0029e4b5 100644 --- a/model_server/tests/test_app.py +++ b/model_server/tests/test_app.py @@ -8,7 +8,6 @@ from src.main import app client = TestClient(app) -# [TODO] Review: check the following code. Seems something wrong with asyncio package❗ # Unit tests for the health check endpoint @pytest.mark.asyncio async def test_healthz(): @@ -17,7 +16,6 @@ async def test_healthz(): assert response.json() == {"status": "ok"} -# [TODO] Review: check the following code. Seems something wrong with asyncio package❗ # Unit test for the models endpoint @pytest.mark.asyncio async def test_models(): @@ -27,17 +25,14 @@ async def test_models(): assert len(response.json()["data"]) > 0 -# [TODO] Review: check the following code. Seems something wrong with asyncio package❗ # Unit test for the guardrail endpoint @pytest.mark.asyncio async def test_guardrail_endpoint(): request_data = {"input": "Test for jailbreak and toxicity", "task": "jailbreak"} response = client.post("/guardrails", json=request_data) assert response.status_code == 200 - assert "response" in response.json() -# [TODO] Review: check the following code. Seems something wrong with asyncio package❗ # Unit test for the function calling endpoint @pytest.mark.asyncio async def test_function_calling_endpoint(): @@ -50,4 +45,3 @@ async def test_function_calling_endpoint(): } response = await client.post("/function_calling", json=request_data) assert response.status_code == 200 - assert "result" in response.json() diff --git a/tests/modelserver/poetry.lock b/tests/modelserver/poetry.lock index 956bd619..d4a0640f 100644 --- a/tests/modelserver/poetry.lock +++ b/tests/modelserver/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "attrs" @@ -111,116 +111,103 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.4.0" +version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.7" files = [ - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, - {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, - {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, - {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, - {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, - {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, - {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, - {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, - {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, - {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, ] [[package]] @@ -236,75 +223,78 @@ files = [ [[package]] name = "coverage" -version = "7.6.9" +version = "7.6.10" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:85d9636f72e8991a1706b2b55b06c27545448baf9f6dbf51c4004609aacd7dcb"}, - {file = "coverage-7.6.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:608a7fd78c67bee8936378299a6cb9f5149bb80238c7a566fc3e6717a4e68710"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96d636c77af18b5cb664ddf12dab9b15a0cfe9c0bde715da38698c8cea748bfa"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cded8a3cff93da9edc31446872d2997e327921d8eed86641efafd350e1df1"}, - {file = "coverage-7.6.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7b15f589593110ae767ce997775d645b47e5cbbf54fd322f8ebea6277466cec"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:44349150f6811b44b25574839b39ae35291f6496eb795b7366fef3bd3cf112d3"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d891c136b5b310d0e702e186d70cd16d1119ea8927347045124cb286b29297e5"}, - {file = "coverage-7.6.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:db1dab894cc139f67822a92910466531de5ea6034ddfd2b11c0d4c6257168073"}, - {file = "coverage-7.6.9-cp310-cp310-win32.whl", hash = "sha256:41ff7b0da5af71a51b53f501a3bac65fb0ec311ebed1632e58fc6107f03b9198"}, - {file = "coverage-7.6.9-cp310-cp310-win_amd64.whl", hash = "sha256:35371f8438028fdccfaf3570b31d98e8d9eda8bb1d6ab9473f5a390969e98717"}, - {file = "coverage-7.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:932fc826442132dde42ee52cf66d941f581c685a6313feebed358411238f60f9"}, - {file = "coverage-7.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:085161be5f3b30fd9b3e7b9a8c301f935c8313dcf928a07b116324abea2c1c2c"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc660a77e1c2bf24ddbce969af9447a9474790160cfb23de6be4fa88e3951c7"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c69e42c892c018cd3c8d90da61d845f50a8243062b19d228189b0224150018a9"}, - {file = "coverage-7.6.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0824a28ec542a0be22f60c6ac36d679e0e262e5353203bea81d44ee81fe9c6d4"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4401ae5fc52ad8d26d2a5d8a7428b0f0c72431683f8e63e42e70606374c311a1"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98caba4476a6c8d59ec1eb00c7dd862ba9beca34085642d46ed503cc2d440d4b"}, - {file = "coverage-7.6.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee5defd1733fd6ec08b168bd4f5387d5b322f45ca9e0e6c817ea6c4cd36313e3"}, - {file = "coverage-7.6.9-cp311-cp311-win32.whl", hash = "sha256:f2d1ec60d6d256bdf298cb86b78dd715980828f50c46701abc3b0a2b3f8a0dc0"}, - {file = "coverage-7.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:0d59fd927b1f04de57a2ba0137166d31c1a6dd9e764ad4af552912d70428c92b"}, - {file = "coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8"}, - {file = "coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3"}, - {file = "coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6"}, - {file = "coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f"}, - {file = "coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692"}, - {file = "coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97"}, - {file = "coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664"}, - {file = "coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00"}, - {file = "coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077"}, - {file = "coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb"}, - {file = "coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba"}, - {file = "coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1"}, - {file = "coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419"}, - {file = "coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae"}, - {file = "coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e"}, - {file = "coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9"}, - {file = "coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b"}, - {file = "coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611"}, - {file = "coverage-7.6.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:adb697c0bd35100dc690de83154627fbab1f4f3c0386df266dded865fc50a902"}, - {file = "coverage-7.6.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:be57b6d56e49c2739cdf776839a92330e933dd5e5d929966fbbd380c77f060be"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1592791f8204ae9166de22ba7e6705fa4ebd02936c09436a1bb85aabca3e599"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e12ae8cc979cf83d258acb5e1f1cf2f3f83524d1564a49d20b8bec14b637f08"}, - {file = "coverage-7.6.9-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5555cff66c4d3d6213a296b360f9e1a8e323e74e0426b6c10ed7f4d021e464"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9389a429e0e5142e69d5bf4a435dd688c14478a19bb901735cdf75e57b13845"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:592ac539812e9b46046620341498caf09ca21023c41c893e1eb9dbda00a70cbf"}, - {file = "coverage-7.6.9-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a27801adef24cc30871da98a105f77995e13a25a505a0161911f6aafbd66e678"}, - {file = "coverage-7.6.9-cp39-cp39-win32.whl", hash = "sha256:8e3c3e38930cfb729cb8137d7f055e5a473ddaf1217966aa6238c88bd9fd50e6"}, - {file = "coverage-7.6.9-cp39-cp39-win_amd64.whl", hash = "sha256:e28bf44afa2b187cc9f41749138a64435bf340adfcacb5b2290c070ce99839d4"}, - {file = "coverage-7.6.9-pp39.pp310-none-any.whl", hash = "sha256:f3ca78518bc6bc92828cd11867b121891d75cae4ea9e908d72030609b996db1b"}, - {file = "coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, + {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, + {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, + {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, + {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, + {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, + {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, + {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, + {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, + {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, + {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, + {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, + {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, + {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, + {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, ] +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + [package.extras] toml = ["tomli"] @@ -326,6 +316,20 @@ orderly-set = ">=5.2.3,<6" cli = ["click (==8.1.7)", "pyyaml (==6.0.2)"] optimize = ["orjson"] +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "h11" version = "0.14.0" @@ -519,9 +523,11 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] @@ -733,19 +739,61 @@ files = [ tests = ["pytest", "pytest-cov"] [[package]] -name = "trio" -version = "0.27.0" -description = "A friendly Python library for async concurrency and I/O" +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" optional = false python-versions = ">=3.8" files = [ - {file = "trio-0.27.0-py3-none-any.whl", hash = "sha256:68eabbcf8f457d925df62da780eff15ff5dc68fd6b367e2dde59f7aaf2a0b884"}, - {file = "trio-0.27.0.tar.gz", hash = "sha256:1dcc95ab1726b2da054afea8fd761af74bad79bd52381b84eae408e983c76831"}, + {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 = "trio" +version = "0.28.0" +description = "A friendly Python library for async concurrency and I/O" +optional = false +python-versions = ">=3.9" +files = [ + {file = "trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94"}, + {file = "trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05"}, ] [package.dependencies] attrs = ">=23.2.0" cffi = {version = ">=1.14", markers = "os_name == \"nt\" and implementation_name != \"pypy\""} +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = "*" outcome = "*" sniffio = ">=1.3.0" @@ -763,6 +811,7 @@ files = [ ] [package.dependencies] +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} trio = ">=0.11" wsproto = ">=0.14" @@ -779,13 +828,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.3" +version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, - {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, + {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, + {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, ] [package.dependencies] @@ -846,5 +895,5 @@ h11 = ">=0.9.0,<1" [metadata] lock-version = "2.0" -python-versions = "^3.12" -content-hash = "56e809b45f1e4d0ab865523472c7ea4587d1c4b2408ee62ec16d1507aecf0e1d" +python-versions = "^3.10" +content-hash = "d0ba3f1875425991d473c9b6fee9f9cb35de5df5835fd7f7e27e3863ff7d37fe" diff --git a/tests/modelserver/pyproject.toml b/tests/modelserver/pyproject.toml index c328d3c9..af13bfd5 100644 --- a/tests/modelserver/pyproject.toml +++ b/tests/modelserver/pyproject.toml @@ -8,7 +8,7 @@ readme = "README.md" package-mode = false [tool.poetry.dependencies] -python = "^3.12" +python = "^3.10" pytest = "^8.3.3" requests = "^2.29.0" selenium = "^4.11.2" diff --git a/tests/modelserver/test_hallucination.py b/tests/modelserver/test_hallucination.py index 67b487f8..f1a3d9b4 100644 --- a/tests/modelserver/test_hallucination.py +++ b/tests/modelserver/test_hallucination.py @@ -1,13 +1,9 @@ -import json import os import pytest import requests -from deepdiff import DeepDiff import logging import yaml -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) MODEL_SERVER_ENDPOINT = os.getenv( "MODEL_SERVER_ENDPOINT", "http://localhost:51000/function_calling" @@ -37,13 +33,9 @@ def test_model_server(test_data): response = requests.post(MODEL_SERVER_ENDPOINT, json=input) assert response.status_code == 200 - # print(json.dumps(response.json())) - # ensure that response is json assert response.headers["content-type"] == "application/json" + response_json = response.json() assert response_json - metadata = response_json.get("metadata", []) + metadata = response_json.get("metadata", {}) assert (metadata["hallucination"].lower() == "true") == expected[0]["hallucination"] - assert (metadata["prompt_prefilling"].lower() == "true") == expected[0][ - "prompt_prefilling" - ] diff --git a/tests/modelserver/test_hallucination_data.yaml b/tests/modelserver/test_hallucination_data.yaml index 9223edfa..8e6e6b26 100644 --- a/tests/modelserver/test_hallucination_data.yaml +++ b/tests/modelserver/test_hallucination_data.yaml @@ -5,8 +5,7 @@ test_cases: - role: "user" content: "what is the weather forecast for seattle?" tools: - - id: "weather-112" - type: "function" + - type: "function" function: name: "get_current_weather" description: "Get current weather at a location." @@ -14,17 +13,18 @@ test_cases: type: "object" properties: location: - type: "str" + type: "string" description: "The location to get the weather for" format: "City, State" days: - type: "int" - description: "the number of days for the request." - required: ["location", "days"] + type: "integer" + description: "The number of days for the request." + required: + - location + - days expected: - - type: "metadata" - hallucination: false - prompt_prefilling: true + - type: "metadata" + hallucination: false - id: "[WEATHER AGENT] - single turn, single tool, hallucination" input: @@ -32,8 +32,7 @@ test_cases: - role: "user" content: "what is the weather in Seattle in days?" tools: - - id: "weather-112" - type: "function" + - type: "function" function: name: "get_current_weather" description: "Get current weather at a location." @@ -51,7 +50,6 @@ test_cases: expected: - type: "metadata" hallucination: true - prompt_prefilling: true - id: "[WEATHER AGENT] - multi turn, single tool, all params passed" input: @@ -85,8 +83,6 @@ test_cases: expected: - type: "metadata" hallucination: true - prompt_prefilling: true - - id: "[WEATHER AGENT] - multi turn, single tool, clarification" input: @@ -120,7 +116,7 @@ test_cases: expected: - type: "metadata" hallucination: false - prompt_prefilling: true + - id: "[SALE AGENT] - single turn, single tool, hallucination region" input: messages: @@ -148,7 +144,6 @@ test_cases: expected: - type: "metadata" hallucination: true - prompt_prefilling: true - id: "[SALE AGENT] - single turn, single tool, hallucination industry" input: @@ -177,7 +172,6 @@ test_cases: expected: - type: "metadata" hallucination: true - prompt_prefilling: true - id: "[PRODUCT AGENT] - single turn, single tool, hallucination industry" input: @@ -261,4 +255,3 @@ test_cases: expected: - type: "metadata" hallucination: true - prompt_prefilling: true diff --git a/tests/modelserver/test_modelserver.py b/tests/modelserver/test_modelserver.py index a8031993..75e6d27e 100644 --- a/tests/modelserver/test_modelserver.py +++ b/tests/modelserver/test_modelserver.py @@ -1,13 +1,10 @@ -import json import os import pytest import requests -from deepdiff import DeepDiff -import logging import yaml -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) +from deepdiff import DeepDiff + MODEL_SERVER_ENDPOINT = os.getenv( "MODEL_SERVER_ENDPOINT", "http://localhost:51000/function_calling" diff --git a/tests/modelserver/test_success_data.yaml b/tests/modelserver/test_success_data.yaml index e34076a8..36e3dcfe 100644 --- a/tests/modelserver/test_success_data.yaml +++ b/tests/modelserver/test_success_data.yaml @@ -107,50 +107,51 @@ test_cases: location: "Los Angeles, CA" days: 5 - - id: "[WEATHER AGENT] - multi turn, single tool, infer param from context" - input: - messages: - - role: "user" - content: "how is the weather in chicago for next 5 days?" - - role: "assistant" - tool_calls: - - id: "call_3394" - type: "function" - function: - name: "get_current_weather" - arguments: - city: "Chicago, IL" - days: 5 - - role: "tool" - content: "--" - tool_call_id: "call_3394" - - role: "assistant" - content: "--" - - role: "user" - content: "how is the weather in LA?" - tools: - - type: "function" - function: - name: "get_current_weather" - description: "Get current weather at a location." - parameters: - type: "object" - properties: - location: - type: "str" - description: "The location to get the weather for" - format: "City, State" - days: - type: "int" - description: "the number of days for the request." - required: ["location", "days"] - expected: - - type: "function" - function: - name: "get_current_weather" - arguments: - location: "Los Angeles, CA" - days: 5 + # Skip! + # - id: "[WEATHER AGENT] - multi turn, single tool, infer param from context" + # input: + # messages: + # - role: "user" + # content: "how is the weather in chicago for next 5 days?" + # - role: "assistant" + # tool_calls: + # - id: "call_3394" + # type: "function" + # function: + # name: "get_current_weather" + # arguments: + # location: "Chicago, IL" + # days: 5 + # - role: "tool" + # content: "--" + # tool_call_id: "call_3394" + # - role: "assistant" + # content: "--" + # - role: "user" + # content: "how is the weather in LA?" + # tools: + # - type: "function" + # function: + # name: "get_current_weather" + # description: "Get current weather at a location." + # parameters: + # type: "object" + # properties: + # location: + # type: "str" + # description: "The location to get the weather for" + # format: "City, State" + # days: + # type: "int" + # description: "the number of days for the request." + # required: ["location", "days"] + # expected: + # - type: "function" + # function: + # name: "get_current_weather" + # arguments: + # location: "Los Angeles, CA" + # days: 5 - id: "[WEATHER AGENT] - multi turn, single tool, infer param from context 2nd try" input: diff --git a/tests/rest/api_model_server.rest b/tests/rest/api_model_server.rest index dea5e884..ed86fac3 100644 --- a/tests/rest/api_model_server.rest +++ b/tests/rest/api_model_server.rest @@ -15,7 +15,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { "name": "get_current_weather", @@ -53,32 +52,30 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", - "type": "function", - "function": { - "name": "get_current_weather", - "description": "Get current weather at a location.", - "parameters": { - "type": "object", - "properties": { - "location": { - "type": "str", - "description": "The location to get the weather for", - "format": "City, State" - }, - "unit": { - "type": "str", - "description": "The unit to return the weather in.", - "enum": ["celsius", "fahrenheit"], - "default": "celsius" - }, - "days": { - "type": "str", - "description": "the number of days for the request." - } - }, - "required": ["location", "days"] + "type": "function", + "function": { + "name": "get_current_weather", + "description": "Get current weather at a location.", + "parameters": { + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The location to get the weather for", + "format": "City, State" + }, + "unit": { + "type": "string", + "description": "The unit to return the weather in.", + "enum": ["celsius", "fahrenheit"], + "default": "celsius" + }, + "days": { + "type": "string", + "description": "The number of days for the request." } + }, + "required": ["location", "days"] } } } @@ -87,6 +84,7 @@ Content-Type: application/json + ### talk to function calling endpoint POST {{model_server_endpoint}}/function_calling HTTP/1.1 Content-Type: application/json @@ -121,7 +119,7 @@ Content-Type: application/json } ### talk to Arch-Intent directly for completion -POST https://api.fc.archgw.com/v1/chat/completions HTTP/1.1 +POST {{archfc_endpoint}}/v1/chat/completions HTTP/1.1 Content-Type: application/json { @@ -212,7 +210,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { "name": "weather_forecast", diff --git a/tests/rest/insurance_agent.rest b/tests/rest/insurance_agent.rest index 0ae0def1..225c7d8a 100644 --- a/tests/rest/insurance_agent.rest +++ b/tests/rest/insurance_agent.rest @@ -31,7 +31,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { "name": "get_current_weather", @@ -103,7 +102,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { "name": "get_current_weather", @@ -172,7 +170,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { @@ -374,7 +371,6 @@ Content-Type: application/json ], "tools": [ { - "id": "weather-112", "type": "function", "function": { From a24d62af1af87112655239dd3b3b0cdb5f9f0935 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Tue, 14 Jan 2025 10:20:27 -0800 Subject: [PATCH 04/18] add github pull request in vscode (#367) --- archgw.code-workspace | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/archgw.code-workspace b/archgw.code-workspace index 50c8a492..78c124e2 100644 --- a/archgw.code-workspace +++ b/archgw.code-workspace @@ -41,15 +41,16 @@ }, "extensions": { "recommendations": [ - "ms-python.python", - "ms-python.debugpy", - "rust-lang.rust-analyzer", - "humao.rest-client", - "github.copilot", "eamodio.gitlens", - "ms-python.black-formatter", - "tamasfe.even-better-toml", "esbenp.prettier-vscode", + "github.copilot", + "github.vscode-pull-request-github", + "humao.rest-client", + "ms-python.black-formatter", + "ms-python.debugpy", + "ms-python.python", + "rust-lang.rust-analyzer", + "tamasfe.even-better-toml", ] } } From 9570b167dbb3d75c2e1fa03d2cf80c8bcef65a54 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Tue, 14 Jan 2025 11:56:10 -0800 Subject: [PATCH 05/18] fix tracing --- crates/common/src/tokenizer.rs | 4 ++-- crates/llm_gateway/src/stream_context.rs | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/crates/common/src/tokenizer.rs b/crates/common/src/tokenizer.rs index aa0870f2..c424e344 100644 --- a/crates/common/src/tokenizer.rs +++ b/crates/common/src/tokenizer.rs @@ -1,4 +1,4 @@ -use log::debug; +use log::trace; #[derive(thiserror::Error, Debug, PartialEq, Eq)] #[allow(dead_code)] @@ -9,7 +9,7 @@ pub enum Error { #[allow(dead_code)] pub fn token_count(model_name: &str, text: &str) -> Result { - debug!("getting token count model={}", model_name); + trace!("getting token count model={}", model_name); // Consideration: is it more expensive to instantiate the BPE object every time, or to contend the singleton? let bpe = tiktoken_rs::get_bpe_from_model(model_name).map_err(|_| Error::UnknownModel { model_name: model_name.to_string(), diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index f0b26ffe..bb36816f 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -312,9 +312,11 @@ impl HttpContext for StreamContext { } fn on_http_response_body(&mut self, body_size: usize, end_of_stream: bool) -> Action { - debug!( + trace!( "on_http_response_body [S={}] bytes={} end_stream={}", - self.context_id, body_size, end_of_stream + self.context_id, + body_size, + end_of_stream ); if !self.is_chat_completions_request { @@ -398,9 +400,10 @@ impl HttpContext for StreamContext { let body = if self.streaming_response { let chunk_start = 0; let chunk_size = body_size; - debug!( + trace!( "streaming response reading, {}..{}", - chunk_start, chunk_size + chunk_start, + chunk_size ); let streaming_chunk = match self.get_http_response_body(0, chunk_size) { Some(chunk) => chunk, @@ -520,9 +523,11 @@ impl HttpContext for StreamContext { } } - debug!( + trace!( "recv [S={}] total_tokens={} end_stream={}", - self.context_id, self.response_tokens, end_of_stream + self.context_id, + self.response_tokens, + end_of_stream ); Action::Continue From 1a10b8272481362187d507223b943de0d71a97ba Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Tue, 14 Jan 2025 16:32:52 -0800 Subject: [PATCH 06/18] pending changes --- arch/arch_config_schema.yaml | 3 ++- arch/envoy.template.yaml | 18 ++++++++++++++++++ arch/tools/cli/config_generator.py | 23 +++++++++++------------ crates/common/src/configuration.rs | 2 ++ crates/llm_gateway/src/stream_context.rs | 5 ++++- tests/archgw/arch_config.yaml | 19 +++++-------------- 6 files changed, 42 insertions(+), 28 deletions(-) diff --git a/arch/arch_config_schema.yaml b/arch/arch_config_schema.yaml index 0fe980dd..67073c79 100644 --- a/arch/arch_config_schema.yaml +++ b/arch/arch_config_schema.yaml @@ -51,11 +51,12 @@ properties: type: string default: type: boolean + endpoint: + type: string additionalProperties: false required: - name - provider - - access_key - model overrides: type: object diff --git a/arch/envoy.template.yaml b/arch/envoy.template.yaml index 5eac257f..3e278c1c 100644 --- a/arch/envoy.template.yaml +++ b/arch/envoy.template.yaml @@ -538,6 +538,24 @@ static_resources: tls_maximum_protocol_version: TLSv1_3 {% endif %} {% endfor %} + +{% for local_llm_provider in local_llms %} + - name: {{ local_llm_provider.name }} + connect_timeout: 5s + type: LOGICAL_DNS + dns_lookup_family: V4_ONLY + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: {{ local_llm_provider.name }} + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: {{ local_llm_provider.endpoint }} + port_value: {{ local_llm_provider.port }} + hostname: {{ local_llm_provider.endpoint }} +{% endfor %} - name: arch_internal connect_timeout: 5s type: LOGICAL_DNS diff --git a/arch/tools/cli/config_generator.py b/arch/tools/cli/config_generator.py index 3393bb5c..5379e909 100644 --- a/arch/tools/cli/config_generator.py +++ b/arch/tools/cli/config_generator.py @@ -16,18 +16,6 @@ ARCH_CONFIG_SCHEMA_FILE = os.getenv( ) -def add_secret_key_to_llm_providers(config_yaml): - llm_providers = [] - for llm_provider in config_yaml.get("llm_providers", []): - access_key_env_var = llm_provider.get("access_key", False) - access_key_value = os.getenv(access_key_env_var, False) - if access_key_env_var and access_key_value: - llm_provider["access_key"] = access_key_value - llm_providers.append(llm_provider) - config_yaml["llm_providers"] = llm_providers - return config_yaml - - def validate_and_render_schema(): env = Environment(loader=FileSystemLoader("./")) template = env.get_template("envoy.template.yaml") @@ -76,12 +64,23 @@ def validate_and_render_schema(): config_yaml["mode"] = "llm" arch_llm_config_string = yaml.dump(config_yaml) + llms_with_endpoint = [] + + for llm_provider in arch_llm_providers: + if llm_provider.get("endpoint", None): + endpoint = llm_provider["endpoint"] + if len(endpoint.split(":")) > 1: + llm_provider["endpoint"] = endpoint.split(":")[0] + llm_provider["port"] = int(endpoint.split(":")[1]) + llms_with_endpoint.append(llm_provider) + data = { "arch_config": arch_config_string, "arch_llm_config": arch_llm_config_string, "arch_clusters": inferred_clusters, "arch_llm_providers": arch_llm_providers, "arch_tracing": arch_tracing, + "local_llms": llms_with_endpoint, } rendered = template.render(data) diff --git a/crates/common/src/configuration.rs b/crates/common/src/configuration.rs index e83c1117..e196be21 100644 --- a/crates/common/src/configuration.rs +++ b/crates/common/src/configuration.rs @@ -171,6 +171,8 @@ pub struct LlmProvider { pub model: String, pub default: Option, pub stream: Option, + pub endpoint: Option, + pub port: Option, pub rate_limits: Option, } diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index bb36816f..50f46ac2 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -177,7 +177,10 @@ impl HttpContext for StreamContext { self.add_http_request_header(ARCH_ROUTING_HEADER, &self.llm_provider().name); if let Err(error) = self.modify_auth_headers() { - self.send_server_error(error, Some(StatusCode::BAD_REQUEST)); + // ensure that the provider has an endpoint if the access key is missing else return a bad request + if self.llm_provider.as_ref().unwrap().endpoint.is_none() { + self.send_server_error(error, Some(StatusCode::BAD_REQUEST)); + } } self.delete_content_length_header(); self.save_ratelimit_header(); diff --git a/tests/archgw/arch_config.yaml b/tests/archgw/arch_config.yaml index 3f450717..e9afa5c1 100644 --- a/tests/archgw/arch_config.yaml +++ b/tests/archgw/arch_config.yaml @@ -12,22 +12,13 @@ endpoints: connect_timeout: 0.005s llm_providers: - - name: gpt-4o-mini - access_key: $OPENAI_API_KEY - provider: openai - model: gpt-4o-mini + + - name: local-llm + provider: local-llm + endpoint: host.docker.internal:51002 + model: test-local-model default: true - - name: gpt-3.5-turbo-0125 - access_key: $OPENAI_API_KEY - provider: openai - model: gpt-3.5-turbo-0125 - - - name: gpt-4o - access_key: $OPENAI_API_KEY - provider: openai - model: gpt-4o - system_prompt: | You are a helpful assistant. From 2413f56980d32a2423ff2c6b1a3215178516f780 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 14:33:59 -0800 Subject: [PATCH 07/18] pending changes --- tests/archgw/arch_config.yaml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/archgw/arch_config.yaml b/tests/archgw/arch_config.yaml index e9afa5c1..3f450717 100644 --- a/tests/archgw/arch_config.yaml +++ b/tests/archgw/arch_config.yaml @@ -12,13 +12,22 @@ endpoints: connect_timeout: 0.005s llm_providers: - - - name: local-llm - provider: local-llm - endpoint: host.docker.internal:51002 - model: test-local-model + - name: gpt-4o-mini + access_key: $OPENAI_API_KEY + provider: openai + model: gpt-4o-mini default: true + - name: gpt-3.5-turbo-0125 + access_key: $OPENAI_API_KEY + provider: openai + model: gpt-3.5-turbo-0125 + + - name: gpt-4o + access_key: $OPENAI_API_KEY + provider: openai + model: gpt-4o + system_prompt: | You are a helpful assistant. From 5017e7931ed9b08a23e8cd45b3734c67621acc65 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 14:37:09 -0800 Subject: [PATCH 08/18] fix tracing --- crates/common/src/tokenizer.rs | 4 ++-- crates/llm_gateway/src/stream_context.rs | 17 ++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/crates/common/src/tokenizer.rs b/crates/common/src/tokenizer.rs index c424e344..aa0870f2 100644 --- a/crates/common/src/tokenizer.rs +++ b/crates/common/src/tokenizer.rs @@ -1,4 +1,4 @@ -use log::trace; +use log::debug; #[derive(thiserror::Error, Debug, PartialEq, Eq)] #[allow(dead_code)] @@ -9,7 +9,7 @@ pub enum Error { #[allow(dead_code)] pub fn token_count(model_name: &str, text: &str) -> Result { - trace!("getting token count model={}", model_name); + debug!("getting token count model={}", model_name); // Consideration: is it more expensive to instantiate the BPE object every time, or to contend the singleton? let bpe = tiktoken_rs::get_bpe_from_model(model_name).map_err(|_| Error::UnknownModel { model_name: model_name.to_string(), diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index 50f46ac2..4df9779e 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -315,11 +315,9 @@ impl HttpContext for StreamContext { } fn on_http_response_body(&mut self, body_size: usize, end_of_stream: bool) -> Action { - trace!( + debug!( "on_http_response_body [S={}] bytes={} end_stream={}", - self.context_id, - body_size, - end_of_stream + self.context_id, body_size, end_of_stream ); if !self.is_chat_completions_request { @@ -403,10 +401,9 @@ impl HttpContext for StreamContext { let body = if self.streaming_response { let chunk_start = 0; let chunk_size = body_size; - trace!( + debug!( "streaming response reading, {}..{}", - chunk_start, - chunk_size + chunk_start, chunk_size ); let streaming_chunk = match self.get_http_response_body(0, chunk_size) { Some(chunk) => chunk, @@ -526,11 +523,9 @@ impl HttpContext for StreamContext { } } - trace!( + debug!( "recv [S={}] total_tokens={} end_stream={}", - self.context_id, - self.response_tokens, - end_of_stream + self.context_id, self.response_tokens, end_of_stream ); Action::Continue From 3fc21de60c9d2e113d65bd8c9971d9ff925d28fd Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 15:11:37 -0800 Subject: [PATCH 09/18] Send per prompt target system prompt (#368) * update prompt target name after arch_fc has identified tool * add test for currency exchange --- crates/prompt_gateway/src/stream_context.rs | 8 ++++++-- tests/rest/api_prompt_gateway.rest | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/crates/prompt_gateway/src/stream_context.rs b/crates/prompt_gateway/src/stream_context.rs index b8a5007f..9782698e 100644 --- a/crates/prompt_gateway/src/stream_context.rs +++ b/crates/prompt_gateway/src/stream_context.rs @@ -263,6 +263,10 @@ impl StreamContext { ); } + // update prompt target name from the tool call + callout_context.prompt_target_name = + Some(self.tool_calls.as_ref().unwrap()[0].function.name.clone()); + self.schedule_api_call_request(callout_context); } @@ -359,8 +363,8 @@ impl StreamContext { let http_status = self .get_http_call_response_header(":status") .unwrap_or(StatusCode::OK.as_str().to_string()); - debug!("api_call_response_handler: http_status: {}", http_status); - if http_status != StatusCode::OK.as_str() { + debug!("api_call_response_handler: http_status: {}", http_status); + if http_status != StatusCode::OK.as_str() { warn!( "api server responded with non 2xx status code: {}", http_status diff --git a/tests/rest/api_prompt_gateway.rest b/tests/rest/api_prompt_gateway.rest index 537b06ac..db06cafe 100644 --- a/tests/rest/api_prompt_gateway.rest +++ b/tests/rest/api_prompt_gateway.rest @@ -100,3 +100,17 @@ Content-Type: application/json ], "stream": true } + +### currency conversion test +POST {{prompt_endpoint}}/v1/chat/completions HTTP/1.1 +Content-Type: application/json + +{ + "model": "--", + "messages": [ + { + "role": "user", + "content": "can you please convert 100 jpy" + } + ] +} From c7f8c2cef93717188927ccbff56046ec0842b9df Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 16:34:17 -0800 Subject: [PATCH 10/18] add demo for ollama --- crates/llm_gateway/src/stream_context.rs | 30 ++++++----- demos/currency_exchange_ollama/README.md | 3 ++ .../currency_exchange_ollama/arch_config.yaml | 52 +++++++++++++++++++ .../docker-compose.yaml | 21 ++++++++ demos/currency_exchange_ollama/run_demo.sh | 47 +++++++++++++++++ 5 files changed, 140 insertions(+), 13 deletions(-) create mode 100644 demos/currency_exchange_ollama/README.md create mode 100644 demos/currency_exchange_ollama/arch_config.yaml create mode 100644 demos/currency_exchange_ollama/docker-compose.yaml create mode 100644 demos/currency_exchange_ollama/run_demo.sh diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index 4df9779e..7169d8cd 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -337,16 +337,18 @@ impl HttpContext for StreamContext { // Record the latency to the latency histogram self.metrics.request_latency.record(duration_ms as u64); - // Compute the time per output token - let tpot = duration_ms as u64 / self.response_tokens as u64; + if self.response_tokens > 0 { + // Compute the time per output token + let tpot = duration_ms as u64 / self.response_tokens as u64; - debug!("Time per output token: {} milliseconds", tpot); - // Record the time per output token - self.metrics.time_per_output_token.record(tpot); + debug!("Time per output token: {} milliseconds", tpot); + // Record the time per output token + self.metrics.time_per_output_token.record(tpot); - debug!("Tokens per second: {}", 1000 / tpot); - // Record the tokens per second - self.metrics.tokens_per_second.record(1000 / tpot); + debug!("Tokens per second: {}", 1000 / tpot); + // Record the tokens per second + self.metrics.tokens_per_second.record(1000 / tpot); + } } Err(e) => { warn!("SystemTime error: {:?}", e); @@ -384,11 +386,13 @@ impl HttpContext for StreamContext { self.llm_provider().name.to_string(), ); - llm_span.add_event(Event::new( - "time_to_first_token".to_string(), - self.ttft_time.unwrap(), - )); - trace_data.add_span(llm_span); + if self.ttft_time.is_some() { + llm_span.add_event(Event::new( + "time_to_first_token".to_string(), + self.ttft_time.unwrap(), + )); + trace_data.add_span(llm_span); + } self.traces_queue.lock().unwrap().push_back(trace_data); } diff --git a/demos/currency_exchange_ollama/README.md b/demos/currency_exchange_ollama/README.md new file mode 100644 index 00000000..ef121a75 --- /dev/null +++ b/demos/currency_exchange_ollama/README.md @@ -0,0 +1,3 @@ +This demo shows how you can use ollama as upstream LLM. + +Before you can start the demo please make sure you have ollama up and running. You can use command `ollama run llama3.2` to start llama 3.2 (3b) model locally at port `11434`. diff --git a/demos/currency_exchange_ollama/arch_config.yaml b/demos/currency_exchange_ollama/arch_config.yaml new file mode 100644 index 00000000..d5a006df --- /dev/null +++ b/demos/currency_exchange_ollama/arch_config.yaml @@ -0,0 +1,52 @@ +version: v0.1 + +listener: + address: 0.0.0.0 + port: 10000 + message_format: huggingface + connect_timeout: 0.005s + +llm_providers: + - name: local-llama + provider: local-llama + model: llama3.2 + endpoint: host.docker.internal:11434 + +system_prompt: | + You are a helpful assistant. + +prompt_guards: + input_guards: + jailbreak: + on_exception: + message: Looks like you're curious about my abilities, but I can only provide assistance for currency exchange. + +prompt_targets: + - name: currency_exchange + description: Get currency exchange rate from USD to other currencies + parameters: + - name: currency_symbol + description: the currency that needs conversion + required: true + type: str + in_path: true + endpoint: + name: frankfurther_api + path: /v1/latest?base=USD&symbols={currency_symbol} + system_prompt: | + You are a helpful assistant. Show me the currency symbol you want to convert from USD. + + - name: get_supported_currencies + description: Get list of supported currencies for conversion + endpoint: + name: frankfurther_api + path: /v1/currencies + +endpoints: + frankfurther_api: + endpoint: api.frankfurter.dev:443 + protocol: https + +tracing: + random_sampling: 100 + trace_arch_internal: true diff --git a/demos/currency_exchange_ollama/docker-compose.yaml b/demos/currency_exchange_ollama/docker-compose.yaml new file mode 100644 index 00000000..32e52c40 --- /dev/null +++ b/demos/currency_exchange_ollama/docker-compose.yaml @@ -0,0 +1,21 @@ +services: + chatbot_ui: + build: + context: ../shared/chatbot_ui + ports: + - "18080:8080" + environment: + # this is only because we are running the sample app in the same docker container environemtn as archgw + - CHAT_COMPLETION_ENDPOINT=http://host.docker.internal:10000/v1 + extra_hosts: + - "host.docker.internal:host-gateway" + volumes: + - ./arch_config.yaml:/app/arch_config.yaml + + jaeger: + build: + context: ../shared/jaeger + ports: + - "16686:16686" + - "4317:4317" + - "4318:4318" diff --git a/demos/currency_exchange_ollama/run_demo.sh b/demos/currency_exchange_ollama/run_demo.sh new file mode 100644 index 00000000..eb47dce6 --- /dev/null +++ b/demos/currency_exchange_ollama/run_demo.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -e + +# Function to start the demo +start_demo() { + # Step 1: Check if .env file exists + if [ -f ".env" ]; then + echo ".env file already exists. Skipping creation." + else + # Step 2: Create `.env` file and set OpenAI key + if [ -z "$OPENAI_API_KEY" ]; then + echo "Error: OPENAI_API_KEY environment variable is not set for the demo." + exit 1 + fi + + echo "Creating .env file..." + echo "OPENAI_API_KEY=$OPENAI_API_KEY" > .env + echo ".env file created with OPENAI_API_KEY." + fi + + # Step 3: Start Arch + echo "Starting Arch with arch_config.yaml..." + archgw up arch_config.yaml + + # Step 4: Start developer services + echo "Starting Network Agent using Docker Compose..." + docker compose up -d # Run in detached mode +} + +# Function to stop the demo +stop_demo() { + # Step 1: Stop Docker Compose services + echo "Stopping Network Agent using Docker Compose..." + docker compose down + + # Step 2: Stop Arch + echo "Stopping Arch..." + archgw down +} + +# Main script logic +if [ "$1" == "down" ]; then + stop_demo +else + # Default action is to bring the demo up + start_demo +fi From 00e4ba55a8df2694f6502c74b247ffc2650d4ea1 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 17:13:45 -0800 Subject: [PATCH 11/18] ensure that only openai is used for provider --- README.md | 2 +- arch/envoy.template.yaml | 4 ++-- crates/common/src/configuration.rs | 8 +++++++- crates/llm_gateway/src/stream_context.rs | 2 +- demos/currency_exchange_ollama/arch_config.yaml | 2 +- .../resources/includes/arch_config_full_reference.yaml | 4 ++-- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c6200745..184aecaf 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ llm_providers: - name: ministral-3b access_key: $MISTRAL_API_KEY - provider: mistral + provider: openai model: ministral-3b-latest ``` diff --git a/arch/envoy.template.yaml b/arch/envoy.template.yaml index 3e278c1c..a145add8 100644 --- a/arch/envoy.template.yaml +++ b/arch/envoy.template.yaml @@ -133,7 +133,7 @@ static_resources: exact: {{ provider.name }} route: auto_host_rewrite: true - cluster: {{ provider.provider }} + cluster: {{ provider.name }} timeout: 60s {% endfor %} http_filters: @@ -378,7 +378,7 @@ static_resources: exact: {{ provider.name }} route: auto_host_rewrite: true - cluster: {{ provider.provider }} + cluster: {{ provider.name }} timeout: 60s {% endfor %} - match: diff --git a/crates/common/src/configuration.rs b/crates/common/src/configuration.rs index e196be21..5fb96ef4 100644 --- a/crates/common/src/configuration.rs +++ b/crates/common/src/configuration.rs @@ -162,11 +162,17 @@ pub struct EmbeddingProviver { pub model: String, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum LlmProviderType { + #[serde(rename = "openai")] + OpenAI +} + #[derive(Debug, Clone, Serialize, Deserialize)] //TODO: use enum for model, but if there is a new model, we need to update the code pub struct LlmProvider { pub name: String, - pub provider: String, + pub provider: LlmProviderType, pub access_key: Option, pub model: String, pub default: Option, diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index 7169d8cd..9bb87de8 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -80,7 +80,7 @@ impl StreamContext { fn select_llm_provider(&mut self) { let provider_hint = self .get_http_request_header(ARCH_PROVIDER_HINT_HEADER) - .map(|provider_name| provider_name.into()); + .map(|llm_name| llm_name.into()); debug!("llm provider hint: {:?}", provider_hint); self.llm_provider = Some(routing::get_llm_provider( diff --git a/demos/currency_exchange_ollama/arch_config.yaml b/demos/currency_exchange_ollama/arch_config.yaml index d5a006df..c555a302 100644 --- a/demos/currency_exchange_ollama/arch_config.yaml +++ b/demos/currency_exchange_ollama/arch_config.yaml @@ -8,7 +8,7 @@ listener: llm_providers: - name: local-llama - provider: local-llama + provider: openai model: llama3.2 endpoint: host.docker.internal:11434 diff --git a/docs/source/resources/includes/arch_config_full_reference.yaml b/docs/source/resources/includes/arch_config_full_reference.yaml index 291f68e5..28f3b123 100644 --- a/docs/source/resources/includes/arch_config_full_reference.yaml +++ b/docs/source/resources/includes/arch_config_full_reference.yaml @@ -46,12 +46,12 @@ llm_providers: unit: minute - name: Mistral8x7b - provider: mistral + provider: openai access_key: $MISTRAL_API_KEY model: mistral-8x7b - name: MistralLocal7b - provider: local + provider: openai model: mistral-7b-instruct endpoint: mistral_local From aa649d5d80a9fc6524cad5b00a714d9f3013d9d1 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 17:18:26 -0800 Subject: [PATCH 12/18] add schema validator for provider --- arch/arch_config_schema.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arch_config_schema.yaml b/arch/arch_config_schema.yaml index 67073c79..ca1d3441 100644 --- a/arch/arch_config_schema.yaml +++ b/arch/arch_config_schema.yaml @@ -45,6 +45,8 @@ properties: type: string provider: type: string + enum: + - openai access_key: type: string model: From 46cca42040eb8c599170720e051ef0ac9a62993a Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Thu, 16 Jan 2025 18:31:40 -0800 Subject: [PATCH 13/18] fix more --- arch/arch_config_schema.yaml | 1 + arch/envoy.template.yaml | 8 ++++---- crates/common/src/configuration.rs | 13 ++++++++++++- crates/llm_gateway/src/stream_context.rs | 11 ++++++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch/arch_config_schema.yaml b/arch/arch_config_schema.yaml index ca1d3441..4e4ec80c 100644 --- a/arch/arch_config_schema.yaml +++ b/arch/arch_config_schema.yaml @@ -47,6 +47,7 @@ properties: type: string enum: - openai + - mistral access_key: type: string model: diff --git a/arch/envoy.template.yaml b/arch/envoy.template.yaml index a145add8..30a4497d 100644 --- a/arch/envoy.template.yaml +++ b/arch/envoy.template.yaml @@ -130,10 +130,10 @@ static_resources: headers: - name: "x-arch-llm-provider" string_match: - exact: {{ provider.name }} + exact: {{ provider.provider }} route: auto_host_rewrite: true - cluster: {{ provider.name }} + cluster: {{ provider.provider }} timeout: 60s {% endfor %} http_filters: @@ -375,10 +375,10 @@ static_resources: headers: - name: "x-arch-llm-provider" string_match: - exact: {{ provider.name }} + exact: {{ provider.provider }} route: auto_host_rewrite: true - cluster: {{ provider.name }} + cluster: {{ provider.provider }} timeout: 60s {% endfor %} - match: diff --git a/crates/common/src/configuration.rs b/crates/common/src/configuration.rs index 5fb96ef4..d0c73c63 100644 --- a/crates/common/src/configuration.rs +++ b/crates/common/src/configuration.rs @@ -165,7 +165,18 @@ pub struct EmbeddingProviver { #[derive(Debug, Clone, Serialize, Deserialize)] pub enum LlmProviderType { #[serde(rename = "openai")] - OpenAI + OpenAI, + #[serde(rename = "mistral")] + Mistral, +} + +impl Display for LlmProviderType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LlmProviderType::OpenAI => write!(f, "openai"), + LlmProviderType::Mistral => write!(f, "mistral"), + } + } } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index 9bb87de8..fba443f0 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -174,7 +174,16 @@ impl HttpContext for StreamContext { // the lifecycle of the http request and response. fn on_http_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action { self.select_llm_provider(); - self.add_http_request_header(ARCH_ROUTING_HEADER, &self.llm_provider().name); + + // if endpoint is not set then use provider name as routing header so envoy can resolve the cluster name + if self.llm_provider().endpoint.is_none() { + self.add_http_request_header( + ARCH_ROUTING_HEADER, + &self.llm_provider().provider.to_string(), + ); + } else { + self.add_http_request_header(ARCH_ROUTING_HEADER, &self.llm_provider().name); + } if let Err(error) = self.modify_auth_headers() { // ensure that the provider has an endpoint if the access key is missing else return a bad request From a7b9458e5aae0f17feeaa39ed9c7a627c76b26b8 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 17 Jan 2025 11:00:36 -0800 Subject: [PATCH 14/18] fix rust tests --- crates/llm_gateway/tests/integration.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/llm_gateway/tests/integration.rs b/crates/llm_gateway/tests/integration.rs index cbaedad3..c43bfcf1 100644 --- a/crates/llm_gateway/tests/integration.rs +++ b/crates/llm_gateway/tests/integration.rs @@ -23,11 +23,15 @@ fn request_headers_expectations(module: &mut Tester, http_context: i32) { Some("x-arch-llm-provider-hint"), ) .returning(Some("default")) - .expect_log(Some(LogLevel::Debug), None) + .expect_log( + Some(LogLevel::Debug), + Some("llm provider hint: Some(Default)"), + ) + .expect_log(Some(LogLevel::Debug), Some("selected llm: open-ai-gpt-4")) .expect_add_header_map_value( Some(MapType::HttpRequestHeaders), Some("x-arch-llm-provider"), - Some("open-ai-gpt-4"), + Some("openai"), ) .expect_replace_header_map_value( Some(MapType::HttpRequestHeaders), @@ -46,8 +50,6 @@ fn request_headers_expectations(module: &mut Tester, http_context: i32) { .returning(None) .expect_get_header_map_value(Some(MapType::HttpRequestHeaders), Some(":path")) .returning(Some("/v1/chat/completions")) - .expect_get_header_map_pairs(Some(MapType::HttpRequestHeaders)) - .returning(None) .expect_log(Some(LogLevel::Debug), None) .expect_get_header_map_value(Some(MapType::HttpRequestHeaders), Some("x-request-id")) .returning(None) From aca1631b49671e829dffb6fbd017b5cb3af66728 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 17 Jan 2025 16:33:17 -0800 Subject: [PATCH 15/18] add more changes --- arch/arch_config_schema.yaml | 6 ++++- arch/envoy.template.yaml | 26 ++++++++++++++----- arch/tools/cli/config_generator.py | 25 +++++++++++++----- crates/common/src/configuration.rs | 2 +- crates/llm_gateway/src/stream_context.rs | 2 +- .../currency_exchange_ollama/arch_config.yaml | 3 ++- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/arch/arch_config_schema.yaml b/arch/arch_config_schema.yaml index 4e4ec80c..e8c7e348 100644 --- a/arch/arch_config_schema.yaml +++ b/arch/arch_config_schema.yaml @@ -43,7 +43,12 @@ properties: properties: name: type: string + # this field is deprecated, use provider_interface instead provider: + type: string + enum: + - openai + provider_interface: type: string enum: - openai @@ -59,7 +64,6 @@ properties: additionalProperties: false required: - name - - provider - model overrides: type: object diff --git a/arch/envoy.template.yaml b/arch/envoy.template.yaml index 30a4497d..17147cc7 100644 --- a/arch/envoy.template.yaml +++ b/arch/envoy.template.yaml @@ -125,15 +125,21 @@ static_resources: - "*" routes: {% for provider in arch_llm_providers %} + # if endpoint is set then use custom cluster for upstream llm + {% if provider.endpoint %} + {% set llm_cluster_name = provider.name %} + {% else %} + {% set llm_cluster_name = provider.provider_interface %} + {% endif %} - match: prefix: "/" headers: - name: "x-arch-llm-provider" string_match: - exact: {{ provider.provider }} + exact: {{ llm_cluster_name }} route: auto_host_rewrite: true - cluster: {{ provider.provider }} + cluster: {{ llm_cluster_name }} timeout: 60s {% endfor %} http_filters: @@ -237,16 +243,16 @@ static_resources: domains: - "*" routes: - {% for internal_clustrer in ["arch_fc", "model_server"] %} + {% for internal_cluster in ["arch_fc", "model_server"] %} - match: prefix: "/" headers: - name: "x-arch-upstream" string_match: - exact: {{ internal_clustrer }} + exact: {{ internal_cluster }} route: auto_host_rewrite: true - cluster: {{ internal_clustrer }} + cluster: {{ internal_cluster }} timeout: 60s {% endfor %} @@ -370,15 +376,21 @@ static_resources: cluster: openai timeout: 60s {% for provider in arch_llm_providers %} + # if endpoint is set then use custom cluster for upstream llm + {% if provider.endpoint %} + {% set llm_cluster_name = provider.name %} + {% else %} + {% set llm_cluster_name = provider.provider_interface %} + {% endif %} - match: prefix: "/" headers: - name: "x-arch-llm-provider" string_match: - exact: {{ provider.provider }} + exact: {{ llm_cluster_name }} route: auto_host_rewrite: true - cluster: {{ provider.provider }} + cluster: {{ llm_cluster_name }} timeout: 60s {% endfor %} - match: diff --git a/arch/tools/cli/config_generator.py b/arch/tools/cli/config_generator.py index 5379e909..e535894b 100644 --- a/arch/tools/cli/config_generator.py +++ b/arch/tools/cli/config_generator.py @@ -58,15 +58,23 @@ def validate_and_render_schema(): f"Unknown endpoint {name}, please add it in endpoints section in your arch_config.yaml file" ) - arch_llm_providers = config_yaml["llm_providers"] arch_tracing = config_yaml.get("tracing", {}) - arch_config_string = yaml.dump(config_yaml) - config_yaml["mode"] = "llm" - arch_llm_config_string = yaml.dump(config_yaml) llms_with_endpoint = [] - for llm_provider in arch_llm_providers: + updated_llm_providers = [] + for llm_provider in config_yaml["llm_providers"]: + provider = None + if llm_provider.get("provider") and llm_provider.get("provider_interface"): + raise Exception( + "Please provide either provider or provider_interface, not both" + ) + if llm_provider.get("provider"): + provider = llm_provider["provider"] + llm_provider["provider_interface"] = provider + del llm_provider["provider"] + updated_llm_providers.append(llm_provider) + if llm_provider.get("endpoint", None): endpoint = llm_provider["endpoint"] if len(endpoint.split(":")) > 1: @@ -74,11 +82,16 @@ def validate_and_render_schema(): llm_provider["port"] = int(endpoint.split(":")[1]) llms_with_endpoint.append(llm_provider) + config_yaml["llm_providers"] = updated_llm_providers + + arch_config_string = yaml.dump(config_yaml) + arch_llm_config_string = yaml.dump(config_yaml) + data = { "arch_config": arch_config_string, "arch_llm_config": arch_llm_config_string, "arch_clusters": inferred_clusters, - "arch_llm_providers": arch_llm_providers, + "arch_llm_providers": config_yaml["llm_providers"], "arch_tracing": arch_tracing, "local_llms": llms_with_endpoint, } diff --git a/crates/common/src/configuration.rs b/crates/common/src/configuration.rs index d0c73c63..fbafe7b9 100644 --- a/crates/common/src/configuration.rs +++ b/crates/common/src/configuration.rs @@ -183,7 +183,7 @@ impl Display for LlmProviderType { //TODO: use enum for model, but if there is a new model, we need to update the code pub struct LlmProvider { pub name: String, - pub provider: LlmProviderType, + pub provider_interface: LlmProviderType, pub access_key: Option, pub model: String, pub default: Option, diff --git a/crates/llm_gateway/src/stream_context.rs b/crates/llm_gateway/src/stream_context.rs index fba443f0..39d4c58f 100644 --- a/crates/llm_gateway/src/stream_context.rs +++ b/crates/llm_gateway/src/stream_context.rs @@ -179,7 +179,7 @@ impl HttpContext for StreamContext { if self.llm_provider().endpoint.is_none() { self.add_http_request_header( ARCH_ROUTING_HEADER, - &self.llm_provider().provider.to_string(), + &self.llm_provider().provider_interface.to_string(), ); } else { self.add_http_request_header(ARCH_ROUTING_HEADER, &self.llm_provider().name); diff --git a/demos/currency_exchange_ollama/arch_config.yaml b/demos/currency_exchange_ollama/arch_config.yaml index c555a302..5936ff17 100644 --- a/demos/currency_exchange_ollama/arch_config.yaml +++ b/demos/currency_exchange_ollama/arch_config.yaml @@ -8,9 +8,10 @@ listener: llm_providers: - name: local-llama - provider: openai + provider_interface: openai model: llama3.2 endpoint: host.docker.internal:11434 + default: true system_prompt: | You are a helpful assistant. From c235eaf7628bd90d2bf53083ff548added67aadb Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 17 Jan 2025 16:39:13 -0800 Subject: [PATCH 16/18] fix test --- .../resources/includes/arch_config_full_reference.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/resources/includes/arch_config_full_reference.yaml b/docs/source/resources/includes/arch_config_full_reference.yaml index 28f3b123..f21fc1f5 100644 --- a/docs/source/resources/includes/arch_config_full_reference.yaml +++ b/docs/source/resources/includes/arch_config_full_reference.yaml @@ -31,7 +31,7 @@ endpoints: # Centralized way to manage LLMs, manage keys, retry logic, failover and limits in a central way llm_providers: - name: OpenAI - provider: openai + provider_interface: openai access_key: $OPENAI_API_KEY model: gpt-4o default: true @@ -46,12 +46,12 @@ llm_providers: unit: minute - name: Mistral8x7b - provider: openai + provider_interface: openai access_key: $MISTRAL_API_KEY model: mistral-8x7b - name: MistralLocal7b - provider: openai + provider_interface: openai model: mistral-7b-instruct endpoint: mistral_local From 36c9c0d414a31a4eac2cfa056c65f0eba35f76ac Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 17 Jan 2025 16:41:55 -0800 Subject: [PATCH 17/18] fix tests --- crates/llm_gateway/tests/integration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/llm_gateway/tests/integration.rs b/crates/llm_gateway/tests/integration.rs index c43bfcf1..7a74dfa8 100644 --- a/crates/llm_gateway/tests/integration.rs +++ b/crates/llm_gateway/tests/integration.rs @@ -112,12 +112,12 @@ endpoints: llm_providers: - name: open-ai-gpt-4 - provider: openai + provider_interface: openai access_key: secret_key model: gpt-4 default: true - name: open-ai-gpt-4o - provider: openai + provider_interface: openai access_key: secret_key model: gpt-4o From 1b3c1b8ba528eaf6ee8037792b633bb4761eb030 Mon Sep 17 00:00:00 2001 From: Adil Hafeez Date: Fri, 17 Jan 2025 16:52:38 -0800 Subject: [PATCH 18/18] fix tests --- crates/prompt_gateway/tests/integration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/prompt_gateway/tests/integration.rs b/crates/prompt_gateway/tests/integration.rs index cb9054f3..1a6ed0e6 100644 --- a/crates/prompt_gateway/tests/integration.rs +++ b/crates/prompt_gateway/tests/integration.rs @@ -131,7 +131,7 @@ endpoints: llm_providers: - name: open-ai-gpt-4 - provider: openai + provider_interface: openai access_key: secret_key model: gpt-4 default: true