From 4b686d7abcb75f12c2047ffaf74c3ce91108caa3 Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Tue, 8 Apr 2025 02:10:38 +1200 Subject: [PATCH 1/8] multi-source search langgraph Signed-off-by: Shuang Yu --- .../.gitignore | 7 + .../CHANGES.rst | 4 + .../LICENSE | 21 + .../README.md | 189 ++ .../agentic_rag.png | Bin 0 -> 13400 bytes .../ai_service.py | 242 ++ .../config.toml.example | 53 + .../examples/_interactive_chat.py | 128 + .../examples/execute_ai_service_locally.py | 31 + .../examples/query_existing_deployment.py | 41 + .../poetry.lock | 2555 +++++++++++++++++ .../pyproject.toml | 26 + .../schema/request.json | 37 + .../schema/response.json | 86 + .../scripts/build_package.py | 58 + .../scripts/deploy.py | 112 + .../src/langgraph_agentic_rag/__init__.py | 1 + .../src/langgraph_agentic_rag/agent.py | 301 ++ .../src/langgraph_agentic_rag/tools.py | 140 + .../tests/__init__.py | 0 .../tests/test_tools.py | 27 + .../utils.py | 10 + 22 files changed, 4069 insertions(+) create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/.gitignore create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/CHANGES.rst create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/LICENSE create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/README.md create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/ai_service.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/config.toml.example create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/examples/_interactive_chat.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/examples/execute_ai_service_locally.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/schema/request.json create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/schema/response.json create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/build_package.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/deploy.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/tests/__init__.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/tests/test_tools.py create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/utils.py diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/.gitignore b/agents/community/langgraph-agentic-rag-multisource-retrieval/.gitignore new file mode 100644 index 00000000..954edc78 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/.gitignore @@ -0,0 +1,7 @@ +.env +.vscode +__pycache__ +.pytest_cache +.venv +dist +config.toml \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/CHANGES.rst b/agents/community/langgraph-agentic-rag-multisource-retrieval/CHANGES.rst new file mode 100644 index 00000000..c49d269f --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/CHANGES.rst @@ -0,0 +1,4 @@ +Version 0.1.0 +------------- + +Base AI service LangGraph template, prepared using `ai-service-template `_ from `IBM/watson-machine-learning-samples` repository. \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/LICENSE b/agents/community/langgraph-agentic-rag-multisource-retrieval/LICENSE new file mode 100644 index 00000000..d8ca6d9e --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 IBM + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md new file mode 100644 index 00000000..7e66f24c --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md @@ -0,0 +1,189 @@ +# A Base LangGraph LLM app template with function calling capabilities + +Table of contents: +* [Introduction](#introduction) +* [Directory structure and file descriptions](#directory-structure-and-file-descriptions) +* [Prerequisites](#prerequisites) +* [Cloning and setting up the template](#cloning-and-setting-up-the-template) +* [Modifying and configuring the template](#modifying-and-configuring-the-template) +* [Running unit tests for the template](#running-unit-tests-for-the-template) +* [Running the application locally](#running-the-application-locally) +* [Deploying on Cloud](#deploying-on-ibm-cloud) +* [Inferencing the deployment](#inferencing-the-deployment) + + +## Introduction + +This repository provides an Agentic RAG template for LLM apps built using LangGraph framework. It also makes it easy to deploy them as an AI service as part of IBM watsonx.ai for IBM Cloud[^1]. +An AI service is a deployable unit of code that captures the logic of your generative AI use case. For and in-depth description of the topic please refer to the [IBM watsonx.ai documentation](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ai-services-templates.html?context=wx&audience=wdp). + +[^1]: _IBM watsonx.ai for IBM Cloud_ is a full and proper name of the component we're using in this template and only a part of the whole suite of products offered in the SaaS model within IBM Cloud environment. Throughout this README, for the sake of simplicity, we'll be calling it just an **IBM Cloud**. + +The template builds an application with IBM watsonx Utility Agent Tool for addressing RAG use case. The structure of RAG graph is as follows + +![alt text](agentic_rag.png "LangGraph Agentic RAG") + +> [!NOTE] +> The template uses predefined `Vector Index Asset` as a source of base knowledge for RAG. For more details about `Vector Index` see https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-prompt-data-index-create.html?context=wx&audience=wdp . To run following Agentic RAG app you should set `tool_config_projectId` and `tool_config_vectorIndexId` in section `deployment.online.parameters` in `config.toml`. Moreover, to help the Agent correctly choose whether or not to use the retriever tool, a description of the underlying knowledge contained in the Vector Index Asset can also be provided in field `base_knowledge_description`. + + +## Directory structure and file descriptions + +The high level structure of the repository is as follows: + +langgraph-agentic-rag + ┣ src + ┃ ┗ langgraph_agentic_rag + ┃ ┣ agent.py + ┃ ┗ tools.py + ┣ schema + ┣ ai_service.py + ┣ config.toml.example + ┣ pyproject.toml + +- `langgraph-agentic-rag` folder: Contains auxiliary files used by the deployed function. They provide various framework specific definitions and extensions. This folder is packaged and sent to IBM Cloud during deployment as a [package extension](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=wx&audience=wdp#custom-wml). +- `schema` folder: Contains request and response schemas for the `/ai_service` endpoint queries. +- `ai_service.py` file: Contains the function to be deployed as an AI service defining the application's logic +- `config.toml.example` file: A configuration file with placeholders that stores the deployment metadata. After downloading the template repository, copy the contents of the `config.toml.example` file to the `config.toml` file and fill in the required fields. `config.toml` file can also be used to tweak the model for your use case. + +## Prerequisites + +- [Poetry](https://python-poetry.org/) package manager, +- [Pipx](https://github.com/pypa/pipx) due to Poetry's recommended [installation procedure](https://python-poetry.org/docs/#installation) + + +## Cloning and setting up the template locally + + +### Step 1: Clone the repository + +In order not to clone the whole `IBM/watsonx-developer-hub` repository we'll use git's shallow and sparse cloning feature to checkout only the template's directory: + +```sh +git clone --no-tags --depth 1 --single-branch --filter=tree:0 --sparse https://github.com/IBM/watsonx-developer-hub.git +cd watsonx-developer-hub +git sparse-checkout add agents/community/langgraph-agentic-rag +``` + +Move to the directory with the agent template: + +```sh +cd agents/community/langgraph-agentic-rag/ +``` + +> [!NOTE] +> From now on it'll be considered that the working directory is `watsonx-developer-hub/agents/community/langgraph-agentic-rag/` + + +### Step 2: Install poetry + +```sh +pipx install --python 3.11 poetry +``` + +### Step 3: Install the template + +Running the below commands will install the repository in a separate virtual environment + +```sh +poetry install +``` + +### Step 4 (OPTIONAL): Activate the virtual environment + +```sh +source $(poetry -q env use 3.11 && poetry env info --path)/bin/activate +``` + +### Step 5: Export PYTHONPATH + +Adding working directory to PYTHONPATH is necessary for the next steps. In your terminal execute: +```sh +export PYTHONPATH=$(pwd):${PYTHONPATH} +``` + +## Modifying and configuring the template + +[config.toml](config.toml) file should be filled in before either deploying the template on IBM Cloud or executing it locally. +Possible config parameters are given in the provided file and explained using comments (when necessary). + + +The template can also be extended to provide additional key-value data to the application. Create a special asset from within your deployment space called _Parameter Sets_. Use the _watsonx.ai_ library to instantiate it and later reference it from the code. +For detailed description and API please refer to the [IBM watsonx.ai Parameter Set's docs](https://ibm.github.io/watsonx-ai-python-sdk/core_api.html#parameter-sets) + + +Sensitive data should not be passed unencrypted, e.g. in the configuration file. The recommended way to handle them is to make use of the [IBM Cloud® Secrets Manager](https://cloud.ibm.com/apidocs/secrets-manager/secrets-manager-v2). The approach to integrating the Secrets Manager's API with the app is for the user to decide on. + + +The [agent.py](src/langgraph/agent.py) file builds app the graph consisting of nodes and edges. The former define the logic for agents while the latter control the logic flow in the whole graph. +For detailed info on how to modify the graph object please refer to [LangGraph's official docs](https://langchain-ai.github.io/langgraph/tutorials/multi_agent/multi-agent-collaboration/#create-graph) + + +The [ai_service.py](ai_service.py) file encompasses the core logic of the app alongside the way of authenticating the user to the IBM Cloud. +For a detailed breakdown of the ai-service's implementation please refer the [IBM Cloud docs](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ai-services-create.html?context=wx) + + +[tools.py](src/langgraph_agentic_rag/tools.py) file stores the definition for tools enhancing the chat model's capabilities. +In order to add new tool create a new function, wrap it with the `@tool` decorator and add to the `TOOLS` list in the `extensions` module's [__init__.py](src/langgraph_agentic_rag/__init__.py) + +For more sophisticated use cases (like async tools), please refer to the [langchain docs](https://python.langchain.com/docs/how_to/custom_tools/#creating-tools-from-runnables). + +## Testing the template + +The `tests/` directory's structure resembles the repository. Adding new tests should follow this convention. +For exemplary purposes only the tools and some general utility functions are covered with unit tests. + +Running the below command will run the complete tests suite: +```sh +pytest -r 'fEsxX' tests/ +``` + +## Running the application locally + +It is possible to run (or even debug) the ai-service locally, however it still requires creating the connection to the IBM Cloud. + +### Step 1: Fill in the `config` file + +Enter the necessary credentials in the `config.toml` file. + +### Step 2: Run the script for local AI service execution + +```sh +python examples/execute_ai_service_locally.py +``` + +### Step 3: Ask the model + +Choose from some pre-defined questions or ask the model your own. + + +## Deploying on IBM Cloud + +Follow these steps to deploy the model on IBM Cloud. + +### Step 1: Fill in the `config` file + +Enter the necessary credentials in the `config.toml` file. + +### Step 2: Run the deployment script + +```sh +python scripts/deploy.py +``` + +Successfully completed script will print on stdout the `deployment_id` which is necessary to locally test the deployment. For further info please refer [to the next section](#querying-the-deployment) + +## Querying the deployment + +Follow these steps to inference your deployment. The [query_existing_deployment.py](examples/query_existing_deployment.py) file shows how to test the existing deployment using `watsonx.ai` library. + +### Step 1: Initialize the deployment ID + +Initialize the `deployment_id` variable in the [query_existing_deployment.py](examples/query_existing_deployment.py) file. +The _deployment_id_ of your deployment can be obtained from [the previous section](#deploying-on-ibm-cloud) by running [scripts/deploy.sh](scripts/deploy.py) + +### Step 2: Run the script for querying the deployment + +```sh +python examples/query_existing_deployment.py +``` diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png b/agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png new file mode 100644 index 0000000000000000000000000000000000000000..d34b91ab4c030ef97bd198e685e65cca66168cfe GIT binary patch literal 13400 zcmZ|01yodD*f%!2ag_HMCJsX5fdEnEG{0jF|qTK#0D;7cocA* z-e8Mc9j0%N+PfY}hFJ*FV%#;)wtz#F>Y2|UisZq%L#JZr;t*tXT2PDUeG7pO7`vZ3 zpF|rK>(%YB^cPN&n(=h6YwQx@>q&2mk1hMXUgnCH?Y_=@^^U87gL^pfsZODBi@t=f zn7TBzs9=o^p6%>Vm&K$UkwJ)#dam}9Z;vr$uL6UwWuAK(b4Gh1mJub5#TvU?eZ=(L zm+-ERg$#%6Nt(gG8%cMHf64X~zUM*8&$-uOKiIvz4ZNKwKPRKe=vrr}yy)qC^nEP) z^d&N)v{y-lyt2p3-1%7hkmh(oK6CN?gN$CY1;SZ`F|yTJ zQFXM~+x{+X=jgN9w+lG!2+78kb!eQ`w&KB4xn=X;iZZ&{S_`F5&4W#m%9)RH@|(@z zcX~f5x%v9NwCIEsAatpV2;<^A^0KbSp04_x-d>*?H#py3oz&LWzB{ z-*DAeiO`4@QNefhBy)81*RLSvou7eN@87?d%^q7>kz!}J>ie z9l>K`V}e#AI=Z@&-hbcrMBY+-_;!R)7e6^M1T*Vp+c@rHSy}P>$?z_Iec4=IqCDxPF`!=t)JgzGd zb4bbU^X;cWOw#Ai75b&`C-cX5-I$m%mzzCjr>8L>2XHtB#E6F)Wj>Lo^iUy&5FZ~C za&>+EGL>%)alZc}L`P2#eKx6H!4}(x1;N9{yuyv@q8R&JMI4spHKqPI#0#^eCLIz0 zrU^f!%AzOozM!R?oSc`p_cQVONug(=qPN%Enav(>a{LgVR+Azf(7&0IR-f~rp63{4 z491V)PR10mf2e~oDjH@cM!__WWj~jal3In`z|VFkQ+SNOrledtR!jO`&`WqZ9WFKE z64Q&qZoMolEEY@rq*j#=k#tX@JIy>FQ81qW!M7&Qp7Ghl#l<~ZsNJ9VuJZWtV0u%w|_SVR#sMccz8f}d{C+KEYp*_3?sS6g-q(w+HOl0Ziy`| zEq$>}SP*L=18eJ@z3CD*awS(+LBD&9(R743ctHk+iXpP`85#CISq`n{Em}Cv2V!>7 zpn+($6L^;<=TJ)%oc5{1(p=4ZZA(i_cXxMl^RMfLa`|CTW~X9fy5;yY8x2X5QRe6?JHPO3$?b<@_)dtc%H2Rfq+#t+~2QXZ5gfn-RE-I zlLhaqxaZ*od@(U0VW!M@e{HSO>%<~k<4QIVd2`7mY%{ge>I+5Ry4s2wok?%aRKi3v z+Eb)7H&)}-ULQu(KAby6&LrqT@8epfPd&3MrS=WOnD&$t^z}Dtmb1B!mgRECYhvD*O7o<+ zHZFN&4w~^985=LQmYhZ8{El&}8c@TYMMyTY>HcC~T!cr&)pVW5Yo{|9-DkIRT0nOY zhEs-zECl%qlrnS#oSD*M;-08Rg?S<&kQ0JsCS$T$%908XY+VsqC%#$v;g< zJGS$iujc$QtvF6(bL8Ll{e{FE_;6wb+OHEK=OmU}Hb;HW68dHhDm=RPj6^jC*EPr@ z6;ctnu9rE5$8B~~LMcCGtQ~(y2jZsmH0rTcx-Q@1daN&!DM29t`i0HTZ4vSXSJ=)V z0Z91Tatmh5Ye(llFugvGZ1DeRHl;(Y%t0p?w2P~4TE^4B$vK#KO25Nn!u2g+gktO} zhOjjTQf_B06j}4SAWl~Pp%+TJcTLlmWQ`=!#q6|cB85z={S|GAaHmal&WrNTvN}&R z`nekS@?Mn?;Nyo9GuU(pU_ktE#rQDG0xY-tkMZB0GBlmzf0{$QPTJesbKjr&o}X_4 z4}Toak7C`$`3g1NF7WTl8yWl2)5^ynbWgXQm7 zzqti_%emm4M*q0ExEoxhQUWlFeq?5M=n`7VuKyg@;&~Y~PM=x}s@>4= zTQZOYoc{WCC=cC9uhmYRt?_8%#uoF95beO_Y|9?NdlN3i7Qv+9$yj9lYImyXX zPm+o!cUj3JqM`^wWXG+AK<3bIo*{mV^o@V!x)m;$^YtrjwnpK!jV(BAY)UBwns0tj zaT9)d=9*t#?zpJ_N&bzOm#7Ehm!PR~hJ=I!eXdvg^|(|?r6-b_;RNci=H75GSM`p33JSxJw1fn7vGlx4uRC)yQYk=rP(J;rCtlV z)_SJoKBA~Xm-OpNwLG}r9yhlRvQGMr;LMrWt<19>8@2~|u-GbAO~Iv#i%tuFbE_> zHLR8(8C!t%9=9<)ltK%d@JbOGPE_>oMgL#mZSUV=`Cligw(RyCo1y+pwSDo3*Qwj1 zr{jL<@Y0~Kkf5yGcKZGyRa-l9eC!L&TniIlcdW2349Lzo;;0QR@KBH_=xqE=?~CY2 z@9kD@E42b~F)<8?0I#Wp`=0)bclX1(qN85wSNd_M4dXyqM`HZF*Z$&|BR4szb)Rfz z$#m7(E$ki~R5?$UG&YhzARyI?rue)zvpPS9O6H(4P{^wjim()J!_&#Y#KpQcPh{_O zF!ac=)eY78MNh8`4MS^EQ_nKNZfPNq%vS>g0}JOTF=J!lSkP~Cb?2=IwqFK(p`k}P zle-)!*X~v5ad-K)ztokXre+6kA2BAx`>*c_aZ@V&^(&&O|byWLo0c^+DBR7ni^ z{RiIc(t}W!`e3#B*WJP45E5Vl!$@RT!-X_7HipI0=;~h)LVj+azIPJ~9;m7Jl-@2m z$3q^#876p<*F7oCU%!3?K;gTVi>T3+nWnq@=F~vMkK|m1J}ECRYKR#h%{S<%Y12mS zjLP${kC+f;l_)bLCKfu4c5FnAImw*jeTl-(CA>{CMF8dVrt2b*<+;AqPwTg?%{l{oY&0vqcF8m;HiJ}x%UKGReUuFql0q{Nj==_jyrR2rZwd|WIG$bI zHZiGrAO#b+jgUPVg?ZrwW2j8qaNVG7x-F}B-4LbSd5;sV>bQqH$V~75@c9TM#jbtD z6(Z~W$5KQ>*1S?5Ou?NHb;D>^m$IKwjiRaFzhOi~?l2hYm_sZ>ZEh~$tzyJhvd1Em z|HSUu@2ocJN#3ccS1F$vh;uxD6@@A<_kc5XktO z^_3Nr=GJD-JI*cp<+@h|v+$Q{YbRd$nMtXsQ&Uq{h|o;|9eJT{@%9H)dpz`|8I3an zR)5cYT8(&Iot!@UOCkn41g+HbzYSC_&J!I7#%pWK@h7pw#kgofy6Pg=;&3Wo54%vOTj zHly#lbRdOW2u&C6e&TV+VgaEgpv~NaXwwEev^%Tu)v_;XyX_^pR(tAvndihuau!-T z%F>q($%^HIXLsQ_ux>;Dut2w7Q)tNn_2Ey?Eb+!_!dKy|HoBi6Lb@d{hzwe(B2CB6 z_5I|gNwzeT^P2SE2|=8LubT?TtshbTeCy$y7l8d;tHYwwTIjT-m}iAcESQ|MlYnui z=j$a&?>7J#&9$@=YBMLMrYM=19N`5uA#>*>&q%RBhM{D{M!(h^oR#fAQL%c=%UfPt zEW7=h5`XjLPaiio_m0HK#W^Q8_i~eaNxQ$E$F@5WU;=^IznAtTmTmMwe9Jc zI;Qk%a8UP&E*gdWfn=teRWF&Qjqar$!OsrXDtcR~KXd42--zVmJbOhthJer?5^92ysc`nDx%j@>`bhO@KxyoxmWE!T- zngDQ2TpVdB!+YFXgN&3EYAPzrc?)~xcE)gcO(uAfl9E!#0)e(PsgTEk{$TR^hlqjA zzXu0)=|lI$g5-057}g&GW)jDfH0l&ijYd-; zLNPS_>j14UbKw#p4Gau~XrpU0EikF6satk&!$xv79xX312RA#0(7R#U8IU|lvJv@O zcrDAdLAU@w2i=%sUkn2vC_ArMl237UKgs9LYZPBut#yW^@R}Z~-Iar*0p_p-kij42 z$J%>!faby!S=~!imuhs|)k<;Hdy+)uj;j(G71ewyMns2o^h-F5r-_d=b$ znIDGDe&RSca_s8g2qAOLo=34zl-J(WV~DhY!2+PK`+Iw$^lE@!{Yv6wU|?7y+ZxYR zsIIPNBacW-oCJKDn%h9`yVji`G|mZ#fd5Fj2mGttgUb4PCP|+&&hi!u5BYE=Of0PJ z;k4PQsg3pZiI7G9u_Hh(qCh6CwYk@l`sK@)>*1%XT(7HGpFB}!C5NxJqgyXmZV>zB zk12n7u72=5-5M6QodImKAS=skwe5q!j|=cJ>-(>j~54CkdeUv3Fun;IlXf*UmYJG5869DIk_+4bzH1l0_G=E(syQJ zBH_!IXa1<$)KnUE_0hSxIq*0%@^Y0tBG3N)=H?~}h3X0;xjZ`~Bq8}nxB>Z$MWyT! zTU2_1E*Upd|Iz$nQqIfCxj$QOy3YZ&$8mORRh0l<(1OX{WI?Qa?t1_Y4P^oO1{vpY zxw+i9nLTm9@56@=etu&}^5vfKaefYt0^2v3pDvY(r)_e_`|T5D@YPBRwTg6}= z^S1JN0krzZrIDJ)NKs8Kl=+c>fXnb#VW&$aW{;zlO}>|h;5}cR&ziQQrF`yNbIYd0;=Y-IbsiDzxcQiw{jRne zHGqzej)obI1I$VrJ#(Su;J_2xcl!6Qjp4{}+SC30{k4Vr3=A1@aT=PMfromPgogDF z_Gx#CSZH?oEGhvIHZd_#Qi?DsS65YS0gMvhU|L#Q7gtwpEiD`(+NlC{ra);@CMNWv zWBYQ8xAr4S%eQZhn%v&^e!9kCBC`D8ckSM&ajx61!MsHkOz+*6>58uZ6P_Z zWhn8#+X|4%wwKAIIWU`yy(eY?vLTlp!+ZyUii4!bSGF>%q_wfR|&>wUZ zh$>hF0N3TsEBd}U-XW=yjBK0nrub97=0fCUByW*FD61*VR#F^UtH# zh=V(%vo%Q7Fz#xgCnhIN=L8ie@PYQY7RIEZQV@WvrKJT!>~ehU#UA68l3E!UxNFNh z)-^m#bdBbmN0ZTEPPKz2^7`>Dh7>;yVShU>#@S+{Yk?6@-vYteBW`Zv8f!AyH<&vq z|E5KcT&}O9Lxw$(MTq?dY7xB3z(&EY8Zc|T>GCXXIMm<6)3e_0Ry8Mh^+KDKTv$W| zKScJs)?IX|&J(aEVrosT`JC6~D)m2gleZ&6!ou3e>U@2DIoR1Pw#j@dz*IaJx!tRO zJCIOURFJB=1)>7~Ii93ihFHikRCxH#WP!Tvy|a^(FT%D|Giuq`!5tMLm$QJ` zf!G%IG}+VR4Quv%i??9sTc(B?UIBqB$JI6n1VoN++Sk7kVHN28U$^St`3mnnf`^U_ z55H7XgI#Z?{Q2`|-1|YW(x$kXpN4$NG}zg!+jqnYR)Yr)Ix``IjDw=|kT}b%ejv%;$3@~)>J^Gb7KtAiGU9n>h^%5^?;$T+_}2`kNj~bNv&FPF2)~aIg|X7O(bc<@(mk7iuaP1ejkLq zq;j`&cC*?QqDfB|bKjc+**#wW!GwD5M>hj5k^u7%8OP62{Q8JlYazT8h`m3bteoZW z*O23G)*>dxYtK*hF*^~tmoi^h^x~A>+KeiB)h_Y= z*UoEK_JhStLSB9*sf4PV(@Q$qy*GU!|Cr(Y)GE1EpJ_Wx*xBRu66$v@dvo1VXttQP zZ^;^yCcurz@T{MjoyC9j;8MCZ&CT8Ax}VUI%zTYU;+}r=G&ED? zM*;P#h{Ce6EgKI@GqbqNOnIX78=9#_4Snxm&UBg zujtze=|yQ!9cFwI{@<9WXy<+2@5E_9q~E{4xnGY%Xw4C*41<}pw_(Ar&~|Jto|ngG zXJCn7L%L%!oRGb`ULArr2JEqYQJ-j*$Da>!ijggoaFRN#)E-`i^xbgK)*Ji?W!?ew z4af@Cwqsm2?N4e}=BPqsO>~Sz&DZ;9)Il^hk~KQ`_)x)rXmF50!fS5&U}#*kl8Z{E zNT=>bqmpL4f!?sHy4rE2<$5d4@oTNzo7;i^%|($*9hDTC#$FPrEScv|+beV7Vf4h* zkl)+eOf)oZ+}n{UDWd=}q;SEeyPs#IHznj#zWcXyN%^dI6uxT(2j2(_O*tw*Jxkk5JYO^^TneQ&Q{T>KdW-?_u&MqyTU7bAlk{TnM z%pZAG^f~hb3a0674mkg~DREnspMy+?_LYs@!N4SBy4hr&f?gwvO$&YraCD{+*aHe-AYKC
L@C?mo*a8;(`N576Pm$7@|kBr;w<0kK8~kUcfE+&=5un+S!tcJ#l8SX4H&w9x-gOUK8@ zzzcdf*W%^(iAR`Lgnv!MMMZ0(jcqaIiksq}Ol_yW6nS1$R#a z25<$S@W1#vT1`ziaoK&v`{dciGTrzy=D`OkgLJgCarzIUpxp5M>%G|O9)Spx$1fhEcv_Gt$}b$xHg-nxv}D?yI)0C*!l?)P`};>m z(M)VSD3O@rza()HAyF= zh?EozxT%Up+dzu7exr>vefN$HOkVWMbAQ0-|II$QM^{(Z{C_T-#ahi|IYNt3``@MLjb-vj zoW1{eLTQhc3#1I%c)5(uau`rMj%NeJv97}IalR@wsKvLPb;5=%jsir`75Unu9Ri`m z`Bw{o4t7!ppcpVgYA*c%0MN_`kgGv=2-4G0Y0N2V1?pdgl$dwqe(A1TJVdTW-s5DH z^ub0S93A=ZjIn@FQko%)wSi=U?K44se@`(93gZT@;X=)ONjZszYH1n)idh63E9+0* z(c9Zw%aQbm-^6qsR0wElqwBVdXu47&do~rCf<(U*UBase9ZHx=DN1sYTa){NA>sOS zZ&!_xizkzc{N1WApHJT$mmr$+Lry~)4>u;$;M-aXErqTLY=?WJ{}r})y$Wa~wL zxWeLAxH_3Ok)sglOhEcB{^;&f(^&tSw*08{AHH5dLCZ{9n`~!!s*~Zf8cCfRXNqc( zv&sEMWq+xje|Scl_N=KHrDvMoDHZ+{W#;-`nC%IPf5}mSY#VA8hO~V@<9+oe&J%mP z0a1}8AVkjL=7}oMyZ$3DcaT_J(wXBFHaQOD^}~Naw8-x%zlKtTI*`|Yg+xmtLBbFAmkBO z%}f_tTPu$5lS1D%azXxKvH~@Rl0vROP7ThLcR7>G;W|zURT8i5D=pT^ zNjB=;h&FCaxkOO6>x0HUJt0gVQV%wE{EoMgNlBZk>=bQh&wtJOquf3I>^l+>-giNx z;2&<L`Fji~=+Wb?nS zOl$7jDXeVIxV3ed*f`&>i=lf;_Rm$W-T%Wtu*JLFc$x^3Ebk?3=|R%L94h`h3X=*O zj#6i}X>;A~%?TM)`1s=DkfG%i9{Zh}{3^kS2YT68Y6*%iQXSPpn?3E^h?}0%Q7Uec~Xv%*t%_%T>Wr|n9TSx(F!B9wwH%MAV~6MnL&3sM;qm@)PSJ2YG4bH(Q_rYd zGA_Ko*O~9mY~RO2AfiSN`y9t;DTs8D4g|6?cWY4c+$olm{ApLa0Q#xs9Y5V7ogKHP zk4ora8B7`QW?c8nB^a4dGUc<5zP1e5GW#B7`GGVcK^vF%= z#nH4EUW6m*Kzqu_KmyAAwYKIHtODn&NMPApfycL4w_z(M7iB*Kvg+y^8k-2{#O<2B zB%~4tB;s6J;9+p$fxoAxz({Fd@ijaCZGOzbOCz7UC0DOY40@wZ{9ipNh z7N0_C0pTxKsL}i-farkh%B)QSlSuTH^;#`VPNa6x&>x;bp;0_V1IYTV;PsrOUj4)RejHE?`)$)&m9M| zRz3il4z^HQTH4`C^Z9UnW-MM*X>l28)C(u7?4>@E$Vh^7pAY{(VAhX)+nkREuUhK0 z9jd~$ug^CD>htE*mS?1lfSSkE!{za#D-MVGuey%FUV}*-zjSp?OiVm2j2|CN`5|mf z8!dlhcUiw$;CH@)yEtW&6c#o+$Xo99ex%diP)t)DH!hOZb9yY<&fD(a~1exQHGAQNc+2MTA1dS8vLF?mVA6#L^^2OeLk#v~;ror9vI zmuVtjYHQ|hjeoq_KNAy2K^5LUwKriSooh!k=CHQNVbosVnEE5#frJ?=B>;U|tB>^c z?URoOwMTT~0OLEXG+i8zx2i)?zqCRwg>rIpySlpK^$ki<5pu(;AJChvH}%4_wSZtO zJ&PhI&-duH!VEA#K9A|y%LHQ{VF=fniBH`G)7NfRj9Ri1OgF?BS&BeSUszh6yx;eENgNP zP=d1AfQ}Ro#6{FeAJczCUh&<#?{W`hEaqW117?~;S40Gn_uXidhI6xzv#w9K(@dD` zzkfh_UDPxQNbr0zk1CYul6ld7c;P?tjjIZQq|2E3y)`InHfIcKxqv$or|*%+G`aEx z#aul<5kr=mVD!Z(hX7CJO>2Eq(*ouR)Kx1@*yhhzrJAZ*EaTQrZST6m1j1#rCh5_g zGwmWBLY!c=r_g3WiuQBOT&E9;sYIHn9~OD-eD4xx>9hR?BenC4_US!!CEI2qz;W(&;=F6&j!sc|xdLO$SIE9XPfrgXb(dZ6KdzzOffRa{`Q;S&%5_5Rb+HwdD!p#iwegtojI zIfaFf`1nX0B{9xUFE4=*-UU=fMMXtv8gJ52$e)y-KYxBp^h@m6Su(hXvB#7+KpE9D znhEV&AQPgI^l>XN5h0U?LZrbRCMJwCCi)p*5I_oIU1T@ta7SIf;xTSI10DbeW`7EOBI0xU-N!a%$J%U0livv1y~x-lkJioPa8dFcL9uz$%zSIGd=;prVMEd zq~0qXHA_o&(5nzo*ysMklOq9!g-blO>o!|v+_gYfQUSz7o~0M5D3bh&isN7sDNq6@ zin+*$5x>U-$pYG7Fb@> z!)#|{S5$TedX*MS_w*2y27(jZ^3k;Jo4@W+mFz2&gcmc>vm$^WWmsp|u@KMWabAfD#`7L_(S2DLD3U%Z7fCpY?P^Phx1%`4yV+d@e-UYH# zMb-rL?KYH(Ym91-Y3QgOZKAJ#b+PF929zzy$IyEt5$+!wHRH|15g3pdMoHz|aVj1= zj^UUe76foBPT&@m6%|$5VZD1iF);xO@wiP&U+&^U=IZPXfxjm&k5lKsWms1VFF#K9 zVq#(%gbr9o+09q62?|o6o;`SAu{HF?S_%n9fA{X)MD~|K{?of|KCLUtqgAyCTo9AK z4Gj%}cLBuW{d1op9iN*E`>AiRn+tevuY9&fYFu30*RMYNGu-<N{`qzz(1yMLZrqjV2X4gc*RN-MlkI1qUV|R{?d&14GWL~^q0siCq9XTD z=9Iy{XgaIbzWIEZQ}z4>#docUkqbC@dTX4IG8a`}cennob6wGDi}z_uYpb_}iS0dL z$v$;lky{(DcU%p9zTFuc>WMORRJIvJt^(&12=YfOt(;U*z!GkUAz{dKy%MR)ni{vs z{Fi{vfhx>_fyZKEKA?p3RW$k?!N2m{k4ZMpxoSLtJE}G+i5LDnbkR?el*{7wYs7dR z9ZSTub$d2lyd@a-P5D1xUATb?PS31ozI?4duIZ9w@9_AD0?$i0wE>mVkW;wS(lF4H&0u{Lrvhdy^r)>Afih?I+%`lU*+w7&D)$x&}s9N6S?8clIY?|^f zU5RP>cMn>zCyzSS&z}e{3zKR(C|hWr7dl8|Lxo1NfpMeMUXv?J)LnJCvvgM%Q&VqD z$W5pm9j@jl)47v^_`n@9Ty1`0wnvbLAT}q8dSO5i!S6qMojWgGx%qWAQo%H(#qjUm z12$P-%pJYgg_JYWYOP|k{G`;Y+27`^UXWHXO97MPMwMdre%c17euwk#717m?-Q-6I z$#&jcf%|si1TDqPq%mz5*PeM#8m|jiy=IS2+`qW;-fkVuox*Pgw=eZ`-_EY6k?^Fc zXGhv1^M=Kga+7-=O2^4Xb-8Xx_*+Zah?kvndOz51p6gdh9_ieeh?b8mG_eH*+USLs zwPJxKwOfRwd7}+JJL8Ee7D^ext-fc4*SVcmT`4Q8lFmj$oC(RHVX>372JfWHvw4TT z44IuUAfI1Ji21G&WLFFgjN49JO~3j})H^;{R;B~rFfTspb4Ql&YLC;*{5|gMaV+1W zkBTy>dbfPCqj@@tyxxTSZvR%%d4l{^Yr3?I>0zg~T!oT*X>8s*orwW?QhR$`ZrDiQ z5jq`4-E!6u-P}I-He5c!xXTQZgCiK&?))QDnRxv5tNF(7T7!;DQVfDV|jfh^;O>wDSO@vy|^F9zg#w476SqPxhjMIz`!D=zD>k9twn z&-)cIS=BoN5nosy!OjJDFrrlIwU8x0e2MR$eeemZhfRo^c~uu0xo? zNPz0fkcBe_giv1GYC@QnE%5|evR6@=6mW*4Xv+_r+%oq%xlKXR||G;G^Zq3}H4r|7Y8(dPBz_wF>nn?Snn z`bw=v9)%M6w3ftv;p%Oe8EuDNS{g(JbL6NFWxQMHCZexf&fLApt6~>#I}K=i!`_qj zW%R_GScTf}8)7!)hNNw8=l3)3+ph;{9BVO?v_g6VzC?V2Qk|EGA7lrMI`jf85L+mp z^h&8#l)+YugJsu4*fuDflg7Y$K>s%SNh$Itq*jMPVB)s;e%YcrM0yT8Z1v*RVxtGm zx1+wUeNNkj0f%>d(m$>9CKk{^i>snte+;-dMmG;0+Ha%mvmud{!8jhL3#JSV5(}+) zx_g_^e_;=Ahoxv&;T#Z1z)+%WQTp!AG76fjGm|%4f103IFiC@9R`)a-3nDt_tIro6 zpv8e1hf{YWnfMU()^5&)LjW~1*OJpI$A^; zgY4WgpJnf@BALKHyF9ta+HzpxQGjEsFeY6ttg|`ukTRAAWGFsC;sU!t<>=HqNOnsVr-2R-jNd1ZL5%CQ0zAly?7)v`f`dLPrr zTQ+cDCy2dJiS{~)G5M?}5{^Ad0?C@BL0wgv6!A6Th|T|Ot4YRr@h0MtSE2Ec-8RpX zngr792|?2Ah{*j6%KieY^2@Af7* z{;nI{$&i_}A#!7n9(c1Wl+h23WOozOEt%L8CLR4IgAocu-Jhgw!G`sy)9@drocNFP z5_a!tDdr072wBcZR0a*?JA3JTlZ@ub5`30?|9UYTCP`&6gjN&_`oAi?hS3;!i+Vjy TCoNWB_8>|x)a1%!&4T_P90UIH literal 0 HcmV?d00001 diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/ai_service.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/ai_service.py new file mode 100644 index 00000000..966c678e --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/ai_service.py @@ -0,0 +1,242 @@ +def deployable_ai_service(context, url, model_id, space_id, thread_id, tool_config_projectId, tool_config_vectorIndexId, base_knowledge_description = None): + from typing import Generator + + from langgraph_agentic_rag.agent import get_graph_closure + from ibm_watsonx_ai import APIClient, Credentials + from langchain_core.messages import ( + BaseMessage, + HumanMessage, + AIMessage, + SystemMessage, + ) + + client = APIClient( + credentials=Credentials(url=url, token=context.generate_token()), + space_id=space_id, + ) + + graph = get_graph_closure( + client, + model_id, + tool_config={ + "projectId": tool_config_projectId, + "vectorIndexId": tool_config_vectorIndexId, + }, + base_knowledge_description=base_knowledge_description, + ) + + def get_formatted_message( + resp: BaseMessage, is_assistant: bool = False + ) -> dict | None: + role = resp.type + + if resp.content: + if role in {"AIMessageChunk", "ai"}: + return {"role": "assistant", "content": resp.content} + elif role == "tool": + if is_assistant: + return { + "role": "assistant", + "step_details": { + "type": "tool_response", + "id": resp.id, + "tool_call_id": resp.tool_call_id, + "name": resp.name, + "content": resp.content, + }, + } + else: + return { + "role": role, + "id": resp.id, + "tool_call_id": resp.tool_call_id, + "name": resp.name, + "content": resp.content, + } + elif role == "ai": # this implies resp.additional_kwargs + if additional_kw := resp.additional_kwargs: + tool_call = additional_kw["tool_calls"][0] + if is_assistant: + return { + "role": "assistant", + "step_details": { + "type": "tool_calls", + "tool_calls": [ + { + "id": tool_call["id"], + "name": tool_call["function"]["name"], + "args": tool_call["function"]["arguments"], + } + ], + }, + } + else: + return { + "role": "assistant", + "tool_calls": [ + { + "id": tool_call["id"], + "type": "function", + "function": { + "name": tool_call["function"]["name"], + "arguments": tool_call["function"]["arguments"], + }, + } + ], + } + + def convert_dict_to_message(_dict: dict) -> BaseMessage: + """Convert user message in dict to langchain_core.messages.BaseMessage""" + + if _dict["role"] == "assistant": + return AIMessage(content=_dict["content"]) + elif _dict["role"] == "system": + return SystemMessage(content=_dict["content"]) + else: + return HumanMessage(content=_dict["content"]) + + def generate(context) -> dict: + """ + The `generate` function handles the REST call to the inference endpoint + POST /ml/v4/deployments/{id_or_name}/ai_service + + The generate function should return a dict + + A JSON body sent to the above endpoint should follow the format: + { + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant that uses tools to answer questions in detail.", + }, + { + "role": "user", + "content": "Hello!", + }, + ] + } + Please note that the `system message` MUST be placed first in the list of messages! + """ + + client.set_token(context.get_token()) + + payload = context.get_json() + raw_messages = payload.get("messages", []) + messages = [convert_dict_to_message(_dict) for _dict in raw_messages] + + if messages and messages[0].type == "system": + agent = graph(messages[0]) + del messages[0] + else: + agent = graph() + + config = { + "configurable": {"thread_id": thread_id} + } # Checkpointer configuration + + # Invoke agent + generated_response = agent.invoke({"messages": messages}, config) + + choices = [] + execute_response = { + "headers": {"Content-Type": "application/json"}, + "body": {"choices": choices}, + } + + choices.append( + { + "index": 0, + "message": get_formatted_message(generated_response["messages"][-1]), + } + ) + + return execute_response + + def generate_stream(context) -> Generator[dict, ..., ...]: + """ + The `generate_stream` function handles the REST call to the Server-Sent Events (SSE) inference endpoint + POST /ml/v4/deployments/{id_or_name}/ai_service_stream + + The generate function should return a dict + + A JSON body sent to the above endpoint should follow the format: + { + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant that uses tools to answer questions in detail.", + }, + { + "role": "user", + "content": "Hello!", + }, + ] + } + Please note that the `system message` MUST be placed first in the list of messages! + """ + try: + headers = context.get_headers() + is_assistant = headers.get("X-Ai-Interface") == "assistant" + + client.set_token(context.get_token()) + + payload = context.get_json() + raw_messages = payload.get("messages", []) + messages = [convert_dict_to_message(_dict) for _dict in raw_messages] + + if messages and messages[0].type == "system": + agent = graph(messages[0]) + del messages[0] + else: + agent = graph() + + + # Checkpointer configuration + config = {"configurable": {"thread_id": thread_id}} + response_stream = agent.stream( + {"messages": messages}, config, stream_mode=["updates", "messages"] + ) + + for chunk_type, data in response_stream: + # print("[data]", data) + if chunk_type == "messages": + msg_obj = data[0] + elif chunk_type == "updates": + if agent := data.get("agent"): + msg_obj = agent["messages"][0] + if msg_obj.response_metadata.get("finish_reason") == "stop": + continue + elif tool := data.get("tools"): + msg_obj = tool["messages"][0] + else: + continue + else: + continue + + if ( + message := get_formatted_message(msg_obj, is_assistant=is_assistant) + ) is not None: + # print(message) + chunk_response = { + "choices": [ + { + "index": 0, + "delta": message, + "finish_reason": msg_obj.response_metadata.get( + "finish_reason" + ), + } + ] + } + yield chunk_response + except Exception as e: + yield { + "choices": [ + { + "index": 0, + "delta": {"role":"assistant", "content":str(e)}, + } + ] + } + + return generate, generate_stream diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/config.toml.example b/agents/community/langgraph-agentic-rag-multisource-retrieval/config.toml.example new file mode 100644 index 00000000..d698827b --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/config.toml.example @@ -0,0 +1,53 @@ +[cli.options] + # If true, cli `invoke` command is trying to use `ai_service.generate_stream` function for local tests, and `ai_service.generate` otherwise. + # Default: true + stream = true + + # Path to json file with a complete payload that will be send to proper AI service generate function. + # Note that, the payload file will be only used when no `query` is provided when running `invoke ` command + # Default: None + payload_path = "" + +[deployment] + # One of the below is required. + # To determine your `api_key`, refer to `IBM Cloud console API keys `_. + watsonx_apikey = "" + watsonx_token = "" + + # should follow the format: `https://{REGION}.ml.cloud.ibm.com` + watsonx_url = "https://us-south.ml.cloud.ibm.com" + + # Deployment space id is required to create deployment with AI service content. + space_id = "01c559cf-a66e-487e-b927-fef28f2961a7" + + # variable, that is populated with last created deployment_id every time when command `watsonx-ai service new` finish successfully + deployment_id = "" + +[deployment.online.parameters] + # during creation of deployment additional parameters can be provided inside `ONLINE` object for further referencing + # please refer to the API docs: https://cloud.ibm.com/apidocs/machine-learning-cp#deployments-create + # model_id = "meta-llama/llama-3-3-70b-instruct" # underlying model of WatsonxChat + model_id = "mistralai/mistral-large" + thread_id = "thread-1" # More info here: https://langchain-ai.github.io/langgraph/how-tos/persistence/ + space_id = "" + url = "https://us-south.ml.cloud.ibm.com" # should follow the format: `https://{REGION}.ml.cloud.ibm.com` + + # RAGQuery Tool configuration + # Required: + tool_config_projectId = "" + tool_config_vectorIndexId = "" + + # Optional: + base_knowledge_description = "" + +[deployment.software_specification] + # Name for derived software specification. If not provided, default one is used that will be build based on the package name: "{pkg_name}-sw-spec" + name = "" + + # Whether to overwrite (delete existing and create new with the same name) watsonx derived software specification + # Default: false + overwrite = false + + # The base software specification used to deploy the AI service. The template dependencies will be installed based on the packages included in the selected base software specification + # Default: "runtime-24.1-py3.11" + base_sw_spec = "runtime-24.1-py3.11" \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/_interactive_chat.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/_interactive_chat.py new file mode 100644 index 00000000..31b5b028 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/_interactive_chat.py @@ -0,0 +1,128 @@ +import textwrap +import json +from collections.abc import Generator +from typing import Callable + + +class InteractiveChat: + def __init__( + self, + ai_service_invoke: Callable, + questions: tuple[str] | None = None, + stream: bool = False, + verbose: bool = True, + ) -> None: + self.ai_service_invoke = ai_service_invoke + self._ordered_list = lambda seq_: "\n".join( + f"\t{i}) {k}" for i, k in enumerate(seq_, 1) + ) + self._delta_start = False + self.verbose = verbose + self.stream = stream + + self.questions = ("Hi! How are you?",) if questions is None else questions + + self._help_message = textwrap.dedent( + """ + The following commands are supported: + --> help | h : prints this help message + --> quit | q : exits the prompt and ends the program + --> list_questions : prints a list of available questions + """ + ) + + @property + def questions(self) -> tuple: + return self._questions + + @questions.setter + def questions(self, q: tuple) -> None: + self._questions = q + self._questions_prompt = ( + f"\tQuestions:\n{self._ordered_list(self._questions)}\n" + ) + + def _user_input_loop(self) -> Generator[tuple[str, str], None, None]: + print(self._help_message) + + while True: + q = input("\nChoose a question or ask one of your own.\n --> ") + + _ = yield q, "question" + + def _print_message(self, choice: dict) -> None: + if delta := choice.get("delta"): + if not self._delta_start: + header = f" {delta['role'].capitalize()} Message ".center(80, "=") + print("\n", header) + self._delta_start = ( + True + and (choice.get("finish_reason") is None) + and delta["role"] != "tool" + ) + print(delta.get("content") or delta.get("tool_calls"), flush=True, end="") + else: + header = f" {choice['message']['role'].capitalize()} Message ".center( + 80, "=" + ) + print("\n", header) + print(f"{choice['message'].get('content', choice['message'])}") + + def run(self) -> None: + # TODO implement signal handling (especially Ctrl-C) + while True: + try: + q = None + + user_loop = self._user_input_loop() + + for action, stage in user_loop: # unsupported command support! + + if action == "h" or action == "help": + print(self._help_message) + elif action == "quit" or action == "q": + raise EOFError + + elif action == "list_questions": + print(self._questions_prompt) + + elif stage == "question": + user_message = {} + # small caveat -- if user answers to the chat a single digit we'll treat it as trying to choose on of our self.questions + if not action.isdigit(): # user defined question + user_message["content"] = action.strip() + else: + number = int(action) + + print(f"you chose QUESTION {number}\n") + if number > len(self.questions) or number < 0: + print( + "provided numbers have to match the available numbers" + ) + else: + user_message["content"] = self.questions[number - 1] + + request_payload_json = { + "messages": [{"role": "user", **user_message}] + } + + resp = self.ai_service_invoke(request_payload_json) + + if self.stream: + for r in resp: + if type(r) == str: + r = json.loads(r) + for c in r["choices"]: + self._print_message(c) + self._delta_start = False + else: + resp_choices = resp.get("body", resp)["choices"] + choices = ( + resp_choices if self.verbose else resp_choices[-1:] + ) + + for c in choices: + self._print_message(c) + + except EOFError: + break diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/execute_ai_service_locally.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/execute_ai_service_locally.py new file mode 100644 index 00000000..2d479e08 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/execute_ai_service_locally.py @@ -0,0 +1,31 @@ +from ibm_watsonx_ai import APIClient, Credentials +from ibm_watsonx_ai.deployments import RuntimeContext + +from ai_service import deployable_ai_service +from utils import load_config +from examples._interactive_chat import InteractiveChat + +stream = True +config = load_config() +dep_config = config["deployment"] +online_parameters = dep_config["online"]["parameters"] + +client = APIClient( + credentials=Credentials( + url=dep_config["watsonx_url"], api_key=dep_config["watsonx_apikey"] + ) +) + +context = RuntimeContext(api_client=client) +ai_service_resp_func = deployable_ai_service(context=context, **online_parameters)[ + stream +] + + +def ai_service_invoke(payload): + context.request_payload_json = payload + return ai_service_resp_func(context) + + +chat = InteractiveChat(ai_service_invoke, stream=stream) +chat.run() diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py new file mode 100644 index 00000000..c2ba3925 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py @@ -0,0 +1,41 @@ +import ibm_watsonx_ai + +from utils import load_config +from examples._interactive_chat import InteractiveChat + +deployment_id = "b7d2a4d0-0a97-42c2-80ea-8c39623a14d8" +stream = True +config = load_config("deployment") + +client = ibm_watsonx_ai.APIClient( + credentials=ibm_watsonx_ai.Credentials( + url=config["watsonx_url"], api_key=config["watsonx_apikey"] + ), + space_id=config["space_id"], +) + +# # Executing deployed AI service with provided scoring data +# if stream: +# ai_service_invoke = lambda payload: client.deployments.run_ai_service_stream( +# deployment_id, payload +# ) +# else: +# ai_service_invoke = lambda payload: client.deployments.run_ai_service( +# deployment_id, payload +# ) + +# chat = InteractiveChat(ai_service_invoke, stream=stream) +# chat.run() + +payload = { + "messages": [ + { + "role": "user", + "content": "what's ibm's carbon emission" + } + ] + } + +for chunk in client.deployments.run_ai_service_stream(deployment_id, payload): + print(chunk) + diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock b/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock new file mode 100644 index 00000000..84eb7ac1 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock @@ -0,0 +1,2555 @@ +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +description = "Happy Eyeballs for asyncio" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8"}, + {file = "aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558"}, +] + +[[package]] +name = "aiohttp" +version = "3.11.16" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiohttp-3.11.16-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb46bb0f24813e6cede6cc07b1961d4b04f331f7112a23b5e21f567da4ee50aa"}, + {file = "aiohttp-3.11.16-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:54eb3aead72a5c19fad07219acd882c1643a1027fbcdefac9b502c267242f955"}, + {file = "aiohttp-3.11.16-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:38bea84ee4fe24ebcc8edeb7b54bf20f06fd53ce4d2cc8b74344c5b9620597fd"}, + {file = "aiohttp-3.11.16-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0666afbe984f6933fe72cd1f1c3560d8c55880a0bdd728ad774006eb4241ecd"}, + {file = "aiohttp-3.11.16-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba92a2d9ace559a0a14b03d87f47e021e4fa7681dc6970ebbc7b447c7d4b7cd"}, + {file = "aiohttp-3.11.16-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ad1d59fd7114e6a08c4814983bb498f391c699f3c78712770077518cae63ff7"}, + {file = "aiohttp-3.11.16-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b88a2bf26965f2015a771381624dd4b0839034b70d406dc74fd8be4cc053e3"}, + {file = "aiohttp-3.11.16-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:576f5ca28d1b3276026f7df3ec841ae460e0fc3aac2a47cbf72eabcfc0f102e1"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a2a450bcce4931b295fc0848f384834c3f9b00edfc2150baafb4488c27953de6"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:37dcee4906454ae377be5937ab2a66a9a88377b11dd7c072df7a7c142b63c37c"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4d0c970c0d602b1017e2067ff3b7dac41c98fef4f7472ec2ea26fd8a4e8c2149"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:004511d3413737700835e949433536a2fe95a7d0297edd911a1e9705c5b5ea43"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:c15b2271c44da77ee9d822552201180779e5e942f3a71fb74e026bf6172ff287"}, + {file = "aiohttp-3.11.16-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ad9509ffb2396483ceacb1eee9134724443ee45b92141105a4645857244aecc8"}, + {file = "aiohttp-3.11.16-cp310-cp310-win32.whl", hash = "sha256:634d96869be6c4dc232fc503e03e40c42d32cfaa51712aee181e922e61d74814"}, + {file = "aiohttp-3.11.16-cp310-cp310-win_amd64.whl", hash = "sha256:938f756c2b9374bbcc262a37eea521d8a0e6458162f2a9c26329cc87fdf06534"}, + {file = "aiohttp-3.11.16-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8cb0688a8d81c63d716e867d59a9ccc389e97ac7037ebef904c2b89334407180"}, + {file = "aiohttp-3.11.16-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ad1fb47da60ae1ddfb316f0ff16d1f3b8e844d1a1e154641928ea0583d486ed"}, + {file = "aiohttp-3.11.16-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:df7db76400bf46ec6a0a73192b14c8295bdb9812053f4fe53f4e789f3ea66bbb"}, + {file = "aiohttp-3.11.16-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc3a145479a76ad0ed646434d09216d33d08eef0d8c9a11f5ae5cdc37caa3540"}, + {file = "aiohttp-3.11.16-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d007aa39a52d62373bd23428ba4a2546eed0e7643d7bf2e41ddcefd54519842c"}, + {file = "aiohttp-3.11.16-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6ddd90d9fb4b501c97a4458f1c1720e42432c26cb76d28177c5b5ad4e332601"}, + {file = "aiohttp-3.11.16-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a2f451849e6b39e5c226803dcacfa9c7133e9825dcefd2f4e837a2ec5a3bb98"}, + {file = "aiohttp-3.11.16-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8df6612df74409080575dca38a5237282865408016e65636a76a2eb9348c2567"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:78e6e23b954644737e385befa0deb20233e2dfddf95dd11e9db752bdd2a294d3"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:696ef00e8a1f0cec5e30640e64eca75d8e777933d1438f4facc9c0cdf288a810"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3538bc9fe1b902bef51372462e3d7c96fce2b566642512138a480b7adc9d508"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3ab3367bb7f61ad18793fea2ef71f2d181c528c87948638366bf1de26e239183"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:56a3443aca82abda0e07be2e1ecb76a050714faf2be84256dae291182ba59049"}, + {file = "aiohttp-3.11.16-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:61c721764e41af907c9d16b6daa05a458f066015abd35923051be8705108ed17"}, + {file = "aiohttp-3.11.16-cp311-cp311-win32.whl", hash = "sha256:3e061b09f6fa42997cf627307f220315e313ece74907d35776ec4373ed718b86"}, + {file = "aiohttp-3.11.16-cp311-cp311-win_amd64.whl", hash = "sha256:745f1ed5e2c687baefc3c5e7b4304e91bf3e2f32834d07baaee243e349624b24"}, + {file = "aiohttp-3.11.16-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:911a6e91d08bb2c72938bc17f0a2d97864c531536b7832abee6429d5296e5b27"}, + {file = "aiohttp-3.11.16-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6ac13b71761e49d5f9e4d05d33683bbafef753e876e8e5a7ef26e937dd766713"}, + {file = "aiohttp-3.11.16-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fd36c119c5d6551bce374fcb5c19269638f8d09862445f85a5a48596fd59f4bb"}, + {file = "aiohttp-3.11.16-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d489d9778522fbd0f8d6a5c6e48e3514f11be81cb0a5954bdda06f7e1594b321"}, + {file = "aiohttp-3.11.16-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69a2cbd61788d26f8f1e626e188044834f37f6ae3f937bd9f08b65fc9d7e514e"}, + {file = "aiohttp-3.11.16-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd464ba806e27ee24a91362ba3621bfc39dbbb8b79f2e1340201615197370f7c"}, + {file = "aiohttp-3.11.16-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ce63ae04719513dd2651202352a2beb9f67f55cb8490c40f056cea3c5c355ce"}, + {file = "aiohttp-3.11.16-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b00dd520d88eac9d1768439a59ab3d145065c91a8fab97f900d1b5f802895e"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7f6428fee52d2bcf96a8aa7b62095b190ee341ab0e6b1bcf50c615d7966fd45b"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:13ceac2c5cdcc3f64b9015710221ddf81c900c5febc505dbd8f810e770011540"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fadbb8f1d4140825069db3fedbbb843290fd5f5bc0a5dbd7eaf81d91bf1b003b"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6a792ce34b999fbe04a7a71a90c74f10c57ae4c51f65461a411faa70e154154e"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:f4065145bf69de124accdd17ea5f4dc770da0a6a6e440c53f6e0a8c27b3e635c"}, + {file = "aiohttp-3.11.16-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fa73e8c2656a3653ae6c307b3f4e878a21f87859a9afab228280ddccd7369d71"}, + {file = "aiohttp-3.11.16-cp312-cp312-win32.whl", hash = "sha256:f244b8e541f414664889e2c87cac11a07b918cb4b540c36f7ada7bfa76571ea2"}, + {file = "aiohttp-3.11.16-cp312-cp312-win_amd64.whl", hash = "sha256:23a15727fbfccab973343b6d1b7181bfb0b4aa7ae280f36fd2f90f5476805682"}, + {file = "aiohttp-3.11.16-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a3814760a1a700f3cfd2f977249f1032301d0a12c92aba74605cfa6ce9f78489"}, + {file = "aiohttp-3.11.16-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9b751a6306f330801665ae69270a8a3993654a85569b3469662efaad6cf5cc50"}, + {file = "aiohttp-3.11.16-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ad497f38a0d6c329cb621774788583ee12321863cd4bd9feee1effd60f2ad133"}, + {file = "aiohttp-3.11.16-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca37057625693d097543bd88076ceebeb248291df9d6ca8481349efc0b05dcd0"}, + {file = "aiohttp-3.11.16-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5abcbba9f4b463a45c8ca8b7720891200658f6f46894f79517e6cd11f3405ca"}, + {file = "aiohttp-3.11.16-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f420bfe862fb357a6d76f2065447ef6f484bc489292ac91e29bc65d2d7a2c84d"}, + {file = "aiohttp-3.11.16-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58ede86453a6cf2d6ce40ef0ca15481677a66950e73b0a788917916f7e35a0bb"}, + {file = "aiohttp-3.11.16-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fdec0213244c39973674ca2a7f5435bf74369e7d4e104d6c7473c81c9bcc8c4"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:72b1b03fb4655c1960403c131740755ec19c5898c82abd3961c364c2afd59fe7"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:780df0d837276276226a1ff803f8d0fa5f8996c479aeef52eb040179f3156cbd"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ecdb8173e6c7aa09eee342ac62e193e6904923bd232e76b4157ac0bfa670609f"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a6db7458ab89c7d80bc1f4e930cc9df6edee2200127cfa6f6e080cf619eddfbd"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2540ddc83cc724b13d1838026f6a5ad178510953302a49e6d647f6e1de82bc34"}, + {file = "aiohttp-3.11.16-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3b4e6db8dc4879015b9955778cfb9881897339c8fab7b3676f8433f849425913"}, + {file = "aiohttp-3.11.16-cp313-cp313-win32.whl", hash = "sha256:493910ceb2764f792db4dc6e8e4b375dae1b08f72e18e8f10f18b34ca17d0979"}, + {file = "aiohttp-3.11.16-cp313-cp313-win_amd64.whl", hash = "sha256:42864e70a248f5f6a49fdaf417d9bc62d6e4d8ee9695b24c5916cb4bb666c802"}, + {file = "aiohttp-3.11.16-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bbcba75fe879ad6fd2e0d6a8d937f34a571f116a0e4db37df8079e738ea95c71"}, + {file = "aiohttp-3.11.16-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:87a6e922b2b2401e0b0cf6b976b97f11ec7f136bfed445e16384fbf6fd5e8602"}, + {file = "aiohttp-3.11.16-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccf10f16ab498d20e28bc2b5c1306e9c1512f2840f7b6a67000a517a4b37d5ee"}, + {file = "aiohttp-3.11.16-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb3d0cc5cdb926090748ea60172fa8a213cec728bd6c54eae18b96040fcd6227"}, + {file = "aiohttp-3.11.16-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d07502cc14ecd64f52b2a74ebbc106893d9a9717120057ea9ea1fd6568a747e7"}, + {file = "aiohttp-3.11.16-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:776c8e959a01e5e8321f1dec77964cb6101020a69d5a94cd3d34db6d555e01f7"}, + {file = "aiohttp-3.11.16-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0902e887b0e1d50424112f200eb9ae3dfed6c0d0a19fc60f633ae5a57c809656"}, + {file = "aiohttp-3.11.16-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e87fd812899aa78252866ae03a048e77bd11b80fb4878ce27c23cade239b42b2"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0a950c2eb8ff17361abd8c85987fd6076d9f47d040ebffce67dce4993285e973"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:c10d85e81d0b9ef87970ecbdbfaeec14a361a7fa947118817fcea8e45335fa46"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7951decace76a9271a1ef181b04aa77d3cc309a02a51d73826039003210bdc86"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14461157d8426bcb40bd94deb0450a6fa16f05129f7da546090cebf8f3123b0f"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9756d9b9d4547e091f99d554fbba0d2a920aab98caa82a8fb3d3d9bee3c9ae85"}, + {file = "aiohttp-3.11.16-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:87944bd16b7fe6160607f6a17808abd25f17f61ae1e26c47a491b970fb66d8cb"}, + {file = "aiohttp-3.11.16-cp39-cp39-win32.whl", hash = "sha256:92b7ee222e2b903e0a4b329a9943d432b3767f2d5029dbe4ca59fb75223bbe2e"}, + {file = "aiohttp-3.11.16-cp39-cp39-win_amd64.whl", hash = "sha256:17ae4664031aadfbcb34fd40ffd90976671fa0c0286e6c4113989f78bebab37a"}, + {file = "aiohttp-3.11.16.tar.gz", hash = "sha256:16f8a2c9538c14a557b4d309ed4d0a7c60f0253e8ed7b6c9a2859a7582f8b1b8"}, +] + +[package.dependencies] +aiohappyeyeballs = ">=2.3.0" +aiosignal = ">=1.1.2" +async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +propcache = ">=0.2.0" +yarl = ">=1.17.0,<2.0" + +[package.extras] +speedups = ["Brotli ; platform_python_implementation == \"CPython\"", "aiodns (>=3.2.0) ; sys_platform == \"linux\" or sys_platform == \"darwin\"", "brotlicffi ; platform_python_implementation != \"CPython\""] + +[[package]] +name = "aiosignal" +version = "1.3.2" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, + {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.9.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c"}, + {file = "anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028"}, +] + +[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 (>=8.2,<9.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx_rtd_theme"] +test = ["anyio[trio]", "blockbuster (>=1.5.23)", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "trustme", "truststore (>=0.9.1) ; python_version >= \"3.10\"", "uvloop (>=0.21) ; platform_python_implementation == \"CPython\" and platform_system != \"Windows\" and python_version < \"3.14\""] +trio = ["trio (>=0.26.1)"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.11\"" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "25.3.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, +] + +[package.extras] +benchmark = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +cov = ["cloudpickle ; platform_python_implementation == \"CPython\"", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +dev = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] +tests = ["cloudpickle ; platform_python_implementation == \"CPython\"", "hypothesis", "mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-xdist[psutil]"] +tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\"", "pytest-mypy-plugins ; platform_python_implementation == \"CPython\" and python_version >= \"3.10\""] + +[[package]] +name = "certifi" +version = "2025.1.31" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, + {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +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" +groups = ["main"] +files = [ + {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 = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["main"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "dataclasses-json" +version = "0.6.7" +description = "Easily serialize dataclasses to and from JSON." +optional = false +python-versions = "<4.0,>=3.7" +groups = ["main"] +files = [ + {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, + {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, +] + +[package.dependencies] +marshmallow = ">=3.18.0,<4.0.0" +typing-inspect = ">=0.4.0,<1" + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "python_version < \"3.11\"" +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 = "frozenlist" +version = "1.5.0" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, + {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, + {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, + {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, + {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, + {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, + {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, + {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, + {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, + {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, + {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, + {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, + {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, +] + +[[package]] +name = "greenlet" +version = "3.1.1" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +groups = ["main"] +markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" +files = [ + {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, + {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, + {file = "greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a"}, + {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511"}, + {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395"}, + {file = "greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39"}, + {file = "greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9"}, + {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0"}, + {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942"}, + {file = "greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01"}, + {file = "greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e"}, + {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1"}, + {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c"}, + {file = "greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822"}, + {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01"}, + {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6"}, + {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47da355d8687fd65240c364c90a31569a133b7b60de111c255ef5b606f2ae291"}, + {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98884ecf2ffb7d7fe6bd517e8eb99d31ff7855a840fa6d0d63cd07c037f6a981"}, + {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1d4aeb8891338e60d1ab6127af1fe45def5259def8094b9c7e34690c8858803"}, + {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db32b5348615a04b82240cc67983cb315309e88d444a288934ee6ceaebcad6cc"}, + {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dcc62f31eae24de7f8dce72134c8651c58000d3b1868e01392baea7c32c247de"}, + {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1d3755bcb2e02de341c55b4fca7a745a24a9e7212ac953f6b3a48d117d7257aa"}, + {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b8da394b34370874b4572676f36acabac172602abf054cbc4ac910219f3340af"}, + {file = "greenlet-3.1.1-cp37-cp37m-win32.whl", hash = "sha256:a0dfc6c143b519113354e780a50381508139b07d2177cb6ad6a08278ec655798"}, + {file = "greenlet-3.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54558ea205654b50c438029505def3834e80f0869a70fb15b871c29b4575ddef"}, + {file = "greenlet-3.1.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:346bed03fe47414091be4ad44786d1bd8bef0c3fcad6ed3dee074a032ab408a9"}, + {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc59d69fc48664bc693842bd57acfdd490acafda1ab52c7836e3fc75c90a111"}, + {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21e10da6ec19b457b82636209cbe2331ff4306b54d06fa04b7c138ba18c8a81"}, + {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37b9de5a96111fc15418819ab4c4432e4f3c2ede61e660b1e33971eba26ef9ba"}, + {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef9ea3f137e5711f0dbe5f9263e8c009b7069d8a1acea822bd5e9dae0ae49c8"}, + {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85f3ff71e2e60bd4b4932a043fbbe0f499e263c628390b285cb599154a3b03b1"}, + {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95ffcf719966dd7c453f908e208e14cde192e09fde6c7186c8f1896ef778d8cd"}, + {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:03a088b9de532cbfe2ba2034b2b85e82df37874681e8c470d6fb2f8c04d7e4b7"}, + {file = "greenlet-3.1.1-cp38-cp38-win32.whl", hash = "sha256:8b8b36671f10ba80e159378df9c4f15c14098c4fd73a36b9ad715f057272fbef"}, + {file = "greenlet-3.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7017b2be767b9d43cc31416aba48aab0d2309ee31b4dbf10a1d38fb7972bdf9d"}, + {file = "greenlet-3.1.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:396979749bd95f018296af156201d6211240e7a23090f50a8d5d18c370084dc3"}, + {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9d0ff5ad43e785350894d97e13633a66e2b50000e8a183a50a88d834752d42"}, + {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f"}, + {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94ebba31df2aa506d7b14866fed00ac141a867e63143fe5bca82a8e503b36437"}, + {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aaad12ac0ff500f62cebed98d8789198ea0e6f233421059fa68a5aa7220145"}, + {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63e4844797b975b9af3a3fb8f7866ff08775f5426925e1e0bbcfe7932059a12c"}, + {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7939aa3ca7d2a1593596e7ac6d59391ff30281ef280d8632fa03d81f7c5f955e"}, + {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0028e725ee18175c6e422797c407874da24381ce0690d6b9396c204c7f7276e"}, + {file = "greenlet-3.1.1-cp39-cp39-win32.whl", hash = "sha256:5e06afd14cbaf9e00899fae69b24a32f2196c19de08fcb9f4779dd4f004e5e7c"}, + {file = "greenlet-3.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:3319aa75e0e0639bc15ff54ca327e8dc7a6fe404003496e3c6925cd3142e0e22"}, + {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, + {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<1.0)"] + +[[package]] +name = "httpx" +version = "0.28.1" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, + {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" + +[package.extras] +brotli = ["brotli ; platform_python_implementation == \"CPython\"", "brotlicffi ; platform_python_implementation != \"CPython\""] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "httpx-sse" +version = "0.4.0" +description = "Consume Server-Sent Event (SSE) messages with HTTPX." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721"}, + {file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"}, +] + +[[package]] +name = "ibm-cos-sdk" +version = "2.13.5" +description = "IBM SDK for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "ibm-cos-sdk-2.13.5.tar.gz", hash = "sha256:1aff7f9863ac9072a3db2f0053bec99478b26f3fb5fa797ce96a15bbb13cd40e"}, +] + +[package.dependencies] +ibm-cos-sdk-core = "2.13.5" +ibm-cos-sdk-s3transfer = "2.13.5" +jmespath = ">=0.10.0,<=1.0.1" + +[[package]] +name = "ibm-cos-sdk-core" +version = "2.13.5" +description = "Low-level, data-driven core of IBM SDK for Python" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "ibm-cos-sdk-core-2.13.5.tar.gz", hash = "sha256:d3a99d8b06b3f8c00b1a9501f85538d592463e63ddf8cec32672ab5a0b107b83"}, +] + +[package.dependencies] +jmespath = ">=0.10.0,<=1.0.1" +python-dateutil = ">=2.9.0,<3.0.0" +requests = ">=2.32.3,<3.0" +urllib3 = {version = ">=1.26.18,<2.2", markers = "python_version >= \"3.10\""} + +[[package]] +name = "ibm-cos-sdk-s3transfer" +version = "2.13.5" +description = "IBM S3 Transfer Manager" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "ibm-cos-sdk-s3transfer-2.13.5.tar.gz", hash = "sha256:9649b1f2201c6de96ff5a6b5a3686de3a809e6ef3b8b12c7c4f2f7ce72da7749"}, +] + +[package.dependencies] +ibm-cos-sdk-core = "2.13.5" + +[[package]] +name = "ibm-watsonx-ai" +version = "1.3.3" +description = "IBM watsonx.ai API Client" +optional = false +python-versions = "<3.13,>=3.10" +groups = ["main"] +files = [ + {file = "ibm_watsonx_ai-1.3.3-py3-none-any.whl", hash = "sha256:f0dd9aadd5b94085b6e22251aafebdd7b5bf1865a7e8c4dca50951c1e89e8e21"}, + {file = "ibm_watsonx_ai-1.3.3.tar.gz", hash = "sha256:b52f3404219e6fa887672c8ba37145a07fd197e2b87bfbfeeb09a24562dd02d8"}, +] + +[package.dependencies] +certifi = "*" +httpx = ">=0.27,<0.29" +ibm-cos-sdk = ">=2.12.0,<2.15.0" +lomond = "*" +packaging = "*" +pandas = ">=0.24.2,<2.3.0" +requests = "*" +tabulate = "*" +urllib3 = "*" + +[package.extras] +fl-crypto = ["pyhelayers (==1.5.0.3)"] +fl-crypto-rt24-1 = ["pyhelayers (==1.5.3.1)"] +fl-rt23-1-py3-10 = ["GPUtil", "cryptography (==42.0.5)", "ddsketch (==2.0.4)", "diffprivlib (==0.5.1)", "environs (==9.5.0)", "gym", "image (==1.5.33)", "joblib (==1.1.1)", "lz4", "msgpack (==1.0.7)", "msgpack-numpy (==0.4.8)", "numcompress (==0.1.2)", "numpy (==1.23.5)", "pandas (==1.5.3)", "parse (==1.19.0)", "pathlib2 (==2.3.6)", "protobuf (==4.22.1)", "psutil", "pyYAML (==6.0.1)", "pytest (==6.2.5)", "requests (==2.32.3)", "scikit-learn (==1.1.1)", "scipy (==1.10.1)", "setproctitle", "skops (==0.9.0)", "skorch (==0.12.0)", "tabulate (==0.8.9)", "tensorflow (==2.12.0)", "torch (==2.0.1)", "websockets (==10.1)"] +fl-rt24-1-py3-11 = ["GPUtil", "cryptography (==42.0.5)", "ddsketch (==2.0.4)", "diffprivlib (==0.5.1)", "environs (==9.5.0)", "gym", "image (==1.5.33)", "joblib (==1.3.2)", "lz4", "msgpack (==1.0.7)", "msgpack-numpy (==0.4.8)", "numcompress (==0.1.2)", "numpy (==1.26.4)", "pandas (==2.1.4)", "parse (==1.19.0)", "pathlib2 (==2.3.6)", "protobuf (==4.22.1)", "psutil", "pyYAML (==6.0.1)", "pytest (==6.2.5)", "requests (==2.32.3)", "scikit-learn (==1.3.0)", "scipy (==1.11.4)", "setproctitle", "skops (==0.9.0)", "skorch (==0.12.0)", "tabulate (==0.8.9)", "tensorflow (==2.14.1)", "torch (==2.1.2)", "websockets (==10.1)"] +rag = ["beautifulsoup4 (==4.12.3)", "grpcio (>=1.54.3)", "langchain (>=0.3,<0.4)", "langchain-chroma (==0.1.4)", "langchain-community (>=0.3,<0.4)", "langchain-core (>=0.3,<0.4)", "langchain-elasticsearch (==0.3.0)", "langchain-ibm (>=0.3,<0.4)", "langchain-milvus (==0.1.7)", "markdown (==3.4.1)", "pypdf (==4.2.0)", "python-docx (==1.1.2)"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "iniconfig" +version = "2.1.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, +] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +groups = ["main"] +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "3.0.0" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, +] + +[[package]] +name = "langchain" +version = "0.3.22" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "langchain-0.3.22-py3-none-any.whl", hash = "sha256:2e7f71a1b0280eb70af9c332c7580f6162a97fb9d5e3e87e9d579ad167f50129"}, + {file = "langchain-0.3.22.tar.gz", hash = "sha256:fd7781ef02cac6f074f9c6a902236482c61976e21da96ab577874d4e5396eeda"}, +] + +[package.dependencies] +async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} +langchain-core = ">=0.3.49,<1.0.0" +langchain-text-splitters = ">=0.3.7,<1.0.0" +langsmith = ">=0.1.17,<0.4" +pydantic = ">=2.7.4,<3.0.0" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" + +[package.extras] +anthropic = ["langchain-anthropic"] +aws = ["langchain-aws"] +azure-ai = ["langchain-azure-ai"] +cohere = ["langchain-cohere"] +community = ["langchain-community"] +deepseek = ["langchain-deepseek"] +fireworks = ["langchain-fireworks"] +google-genai = ["langchain-google-genai"] +google-vertexai = ["langchain-google-vertexai"] +groq = ["langchain-groq"] +huggingface = ["langchain-huggingface"] +mistralai = ["langchain-mistralai"] +ollama = ["langchain-ollama"] +openai = ["langchain-openai"] +together = ["langchain-together"] +xai = ["langchain-xai"] + +[[package]] +name = "langchain-community" +version = "0.3.16" +description = "Community contributed LangChain integrations." +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "langchain_community-0.3.16-py3-none-any.whl", hash = "sha256:a702c577b048d48882a46708bb3e08ca9aec79657c421c3241a305409040c0d6"}, + {file = "langchain_community-0.3.16.tar.gz", hash = "sha256:825709bc328e294942b045d0b7f55053e8e88f7f943576306d778cf56417126c"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +httpx-sse = ">=0.4.0,<0.5.0" +langchain = ">=0.3.16,<0.4.0" +langchain-core = ">=0.3.32,<0.4.0" +langsmith = ">=0.1.125,<0.4" +numpy = [ + {version = ">=1.22.4,<2", markers = "python_version < \"3.12\""}, + {version = ">=1.26.2,<3", markers = "python_version >= \"3.12\""}, +] +pydantic-settings = ">=2.4.0,<3.0.0" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10" + +[[package]] +name = "langchain-core" +version = "0.3.50" +description = "Building applications with LLMs through composability" +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "langchain_core-0.3.50-py3-none-any.whl", hash = "sha256:76b7ff99125d160427801ea47c4b5202363856603e8382208a889fdd914d7d4d"}, + {file = "langchain_core-0.3.50.tar.gz", hash = "sha256:8e141b89f2be6020e94c32d7d5141fc6eb5acf1e04e4d80ebd2c74bf30de9f77"}, +] + +[package.dependencies] +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.1.125,<0.4" +packaging = ">=23.2,<25" +pydantic = [ + {version = ">=2.5.2,<3.0.0", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] +PyYAML = ">=5.3" +tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<10.0.0" +typing-extensions = ">=4.7" + +[[package]] +name = "langchain-ibm" +version = "0.3.10" +description = "An integration package connecting IBM watsonx.ai and LangChain" +optional = false +python-versions = "<3.13,>=3.10" +groups = ["main"] +files = [ + {file = "langchain_ibm-0.3.10-py3-none-any.whl", hash = "sha256:a7c6026879e47f069f7831d5d0cc39a97ae9cf4f75752cbf9b7102cf5ad23fa2"}, + {file = "langchain_ibm-0.3.10.tar.gz", hash = "sha256:a3023903b8b094fe0226c1e3dafb348ed60caf537415ebea9bdf4ceebc6cd4ad"}, +] + +[package.dependencies] +ibm-watsonx-ai = ">=1.2.10,<2.0.0" +langchain-core = ">=0.3.39,<0.4.0" + +[[package]] +name = "langchain-text-splitters" +version = "0.3.7" +description = "LangChain text splitting utilities" +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "langchain_text_splitters-0.3.7-py3-none-any.whl", hash = "sha256:31ba826013e3f563359d7c7f1e99b1cdb94897f665675ee505718c116e7e20ad"}, + {file = "langchain_text_splitters-0.3.7.tar.gz", hash = "sha256:7dbf0fb98e10bb91792a1d33f540e2287f9cc1dc30ade45b7aedd2d5cd3dc70b"}, +] + +[package.dependencies] +langchain-core = ">=0.3.45,<1.0.0" + +[[package]] +name = "langgraph" +version = "0.2.76" +description = "Building stateful, multi-actor applications with LLMs" +optional = false +python-versions = "<4.0,>=3.9.0" +groups = ["main"] +files = [ + {file = "langgraph-0.2.76-py3-none-any.whl", hash = "sha256:076b8b5d2fc5a9761c46a7618430cfa5c978a8012257c43cbc127b27e0fd7872"}, + {file = "langgraph-0.2.76.tar.gz", hash = "sha256:688f8dcd9b6797ba78384599e0de944773000c75156ad1e186490e99e89fa5c0"}, +] + +[package.dependencies] +langchain-core = ">=0.2.43,<0.3.0 || >0.3.0,<0.3.1 || >0.3.1,<0.3.2 || >0.3.2,<0.3.3 || >0.3.3,<0.3.4 || >0.3.4,<0.3.5 || >0.3.5,<0.3.6 || >0.3.6,<0.3.7 || >0.3.7,<0.3.8 || >0.3.8,<0.3.9 || >0.3.9,<0.3.10 || >0.3.10,<0.3.11 || >0.3.11,<0.3.12 || >0.3.12,<0.3.13 || >0.3.13,<0.3.14 || >0.3.14,<0.3.15 || >0.3.15,<0.3.16 || >0.3.16,<0.3.17 || >0.3.17,<0.3.18 || >0.3.18,<0.3.19 || >0.3.19,<0.3.20 || >0.3.20,<0.3.21 || >0.3.21,<0.3.22 || >0.3.22,<0.4.0" +langgraph-checkpoint = ">=2.0.10,<3.0.0" +langgraph-sdk = ">=0.1.42,<0.2.0" + +[[package]] +name = "langgraph-checkpoint" +version = "2.0.24" +description = "Library with base interfaces for LangGraph checkpoint savers." +optional = false +python-versions = "<4.0.0,>=3.9.0" +groups = ["main"] +files = [ + {file = "langgraph_checkpoint-2.0.24-py3-none-any.whl", hash = "sha256:3836e2909ef2387d1fa8d04ee3e2a353f980d519fd6c649af352676dc73d66b8"}, + {file = "langgraph_checkpoint-2.0.24.tar.gz", hash = "sha256:9596dad332344e7e871257be464df8a07c2e9bac66143081b11b9422b0167e5b"}, +] + +[package.dependencies] +langchain-core = ">=0.2.38,<0.4" +ormsgpack = ">=1.8.0,<2.0.0" + +[[package]] +name = "langgraph-sdk" +version = "0.1.61" +description = "SDK for interacting with LangGraph API" +optional = false +python-versions = "<4.0.0,>=3.9.0" +groups = ["main"] +files = [ + {file = "langgraph_sdk-0.1.61-py3-none-any.whl", hash = "sha256:f2d774b12497c428862993090622d51e0dbc3f53e0cee3d74a13c7495d835cc6"}, + {file = "langgraph_sdk-0.1.61.tar.gz", hash = "sha256:87dd1f07ab82da8875ac343268ece8bf5414632017ebc9d1cef4b523962fd601"}, +] + +[package.dependencies] +httpx = ">=0.25.2" +orjson = ">=3.10.1" + +[[package]] +name = "langsmith" +version = "0.3.24" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = "<4.0,>=3.9" +groups = ["main"] +files = [ + {file = "langsmith-0.3.24-py3-none-any.whl", hash = "sha256:24930d34970281950338f6e2724d04a69804ccb3e89dba9314e6086653dc8bc9"}, + {file = "langsmith-0.3.24.tar.gz", hash = "sha256:ee353dae8e59ec91eee8d3b601bc48e9d0e96722d1af14269b314ecb71e22088"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" +orjson = {version = ">=3.9.14,<4.0.0", markers = "platform_python_implementation != \"PyPy\""} +packaging = ">=23.2" +pydantic = [ + {version = ">=1,<3", markers = "python_full_version < \"3.12.4\""}, + {version = ">=2.7.4,<3.0.0", markers = "python_full_version >= \"3.12.4\""}, +] +requests = ">=2,<3" +requests-toolbelt = ">=1.0.0,<2.0.0" +zstandard = ">=0.23.0,<0.24.0" + +[package.extras] +langsmith-pyo3 = ["langsmith-pyo3 (>=0.1.0rc2,<0.2.0)"] +openai-agents = ["openai-agents (>=0.0.3,<0.1)"] +otel = ["opentelemetry-api (>=1.30.0,<2.0.0)", "opentelemetry-exporter-otlp-proto-http (>=1.30.0,<2.0.0)", "opentelemetry-sdk (>=1.30.0,<2.0.0)"] +pytest = ["pytest (>=7.0.0)", "rich (>=13.9.4,<14.0.0)"] + +[[package]] +name = "lomond" +version = "0.3.3" +description = "Websocket Client Library" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "lomond-0.3.3-py2.py3-none-any.whl", hash = "sha256:df1dd4dd7b802a12b71907ab1abb08b8ce9950195311207579379eb3b1553de7"}, + {file = "lomond-0.3.3.tar.gz", hash = "sha256:427936596b144b4ec387ead99aac1560b77c8a78107d3d49415d3abbe79acbd3"}, +] + +[package.dependencies] +six = ">=1.10.0" + +[[package]] +name = "marshmallow" +version = "3.26.1" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "marshmallow-3.26.1-py3-none-any.whl", hash = "sha256:3350409f20a70a7e4e11a27661187b77cdcaeb20abca41c1454fe33636bea09c"}, + {file = "marshmallow-3.26.1.tar.gz", hash = "sha256:e6d8affb6cb61d39d26402096dc0aee12d5a26d490a121f118d2e81dc0719dc6"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] +docs = ["autodocsumm (==0.2.14)", "furo (==2024.8.6)", "sphinx (==8.1.3)", "sphinx-copybutton (==0.5.2)", "sphinx-issues (==5.0.0)", "sphinxext-opengraph (==0.9.1)"] +tests = ["pytest", "simplejson"] + +[[package]] +name = "multidict" +version = "6.3.2" +description = "multidict implementation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "multidict-6.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8b3dc0eec9304fa04d84a51ea13b0ec170bace5b7ddeaac748149efd316f1504"}, + {file = "multidict-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9534f3d84addd3b6018fa83f97c9d4247aaa94ac917d1ed7b2523306f99f5c16"}, + {file = "multidict-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a003ce1413ae01f0b8789c1c987991346a94620a4d22210f7a8fe753646d3209"}, + {file = "multidict-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b43f7384e68b1b982c99f489921a459467b5584bdb963b25e0df57c9039d0ad"}, + {file = "multidict-6.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d142ae84047262dc75c1f92eaf95b20680f85ce11d35571b4c97e267f96fadc4"}, + {file = "multidict-6.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ec7e86fbc48aa1d6d686501a8547818ba8d645e7e40eaa98232a5d43ee4380ad"}, + {file = "multidict-6.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe019fb437632b016e6cac67a7e964f1ef827ef4023f1ca0227b54be354da97e"}, + {file = "multidict-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b60cb81214a9da7cfd8ae2853d5e6e47225ece55fe5833142fe0af321c35299"}, + {file = "multidict-6.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32d9e8ef2e0312d4e96ca9adc88e0675b6d8e144349efce4a7c95d5ccb6d88e0"}, + {file = "multidict-6.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:335d584312e3fa43633d63175dfc1a5f137dd7aa03d38d1310237d54c3032774"}, + {file = "multidict-6.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b8df917faa6b8cac3d6870fc21cb7e4d169faca68e43ffe568c156c9c6408a4d"}, + {file = "multidict-6.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:cc060b9b89b701dd8fedef5b99e1f1002b8cb95072693233a63389d37e48212d"}, + {file = "multidict-6.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f2ce3be2500658f3c644494b934628bb0c82e549dde250d2119689ce791cc8b8"}, + {file = "multidict-6.3.2-cp310-cp310-win32.whl", hash = "sha256:dbcb4490d8e74b484449abd51751b8f560dd0a4812eb5dacc6a588498222a9ab"}, + {file = "multidict-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:06944f9ced30f8602be873563ed4df7e3f40958f60b2db39732c11d615a33687"}, + {file = "multidict-6.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45a034f41fcd16968c0470d8912d293d7b0d0822fc25739c5c2ff7835b85bc56"}, + {file = "multidict-6.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:352585cec45f5d83d886fc522955492bb436fca032b11d487b12d31c5a81b9e3"}, + {file = "multidict-6.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:da9d89d293511fd0a83a90559dc131f8b3292b6975eb80feff19e5f4663647e2"}, + {file = "multidict-6.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fa716592224aa652b9347a586cfe018635229074565663894eb4eb21f8307f"}, + {file = "multidict-6.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0326278a44c56e94792475268e5cd3d47fbc0bd41ee56928c3bbb103ba7f58fe"}, + {file = "multidict-6.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bb1ea87f7fe45e5079f6315e95d64d4ca8b43ef656d98bed63a02e3756853a22"}, + {file = "multidict-6.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cff3c5a98d037024a9065aafc621a8599fad7b423393685dc83cf7a32f8b691"}, + {file = "multidict-6.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed99834b053c655d980fb98029003cb24281e47a796052faad4543aa9e01b8e8"}, + {file = "multidict-6.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7048440e505d2b4741e5d0b32bd2f427c901f38c7760fc245918be2cf69b3b85"}, + {file = "multidict-6.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27248c27b563f5889556da8a96e18e98a56ff807ac1a7d56cf4453c2c9e4cd91"}, + {file = "multidict-6.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6323b4ba0e018bd266f776c35f3f0943fc4ee77e481593c9f93bd49888f24e94"}, + {file = "multidict-6.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:81f7ce5ec7c27d0b45c10449c8f0fed192b93251e2e98cb0b21fec779ef1dc4d"}, + {file = "multidict-6.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03bfcf2825b3bed0ba08a9d854acd18b938cab0d2dba3372b51c78e496bac811"}, + {file = "multidict-6.3.2-cp311-cp311-win32.whl", hash = "sha256:f32c2790512cae6ca886920e58cdc8c784bdc4bb2a5ec74127c71980369d18dc"}, + {file = "multidict-6.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:0b0c15e58e038a2cd75ef7cf7e072bc39b5e0488b165902efb27978984bbad70"}, + {file = "multidict-6.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d1e0ba1ce1b8cc79117196642d95f4365e118eaf5fb85f57cdbcc5a25640b2a4"}, + {file = "multidict-6.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:029bbd7d782251a78975214b78ee632672310f9233d49531fc93e8e99154af25"}, + {file = "multidict-6.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d7db41e3b56817d9175264e5fe00192fbcb8e1265307a59f53dede86161b150e"}, + {file = "multidict-6.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fcab18e65cc555ac29981a581518c23311f2b1e72d8f658f9891590465383be"}, + {file = "multidict-6.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d50eff89aa4d145a5486b171a2177042d08ea5105f813027eb1050abe91839f"}, + {file = "multidict-6.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:643e57b403d3e240045a3681f9e6a04d35a33eddc501b4cbbbdbc9c70122e7bc"}, + {file = "multidict-6.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d17b37b9715b30605b5bab1460569742d0c309e5c20079263b440f5d7746e7e"}, + {file = "multidict-6.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68acd51fa94e63312b8ddf84bfc9c3d3442fe1f9988bbe1b6c703043af8867fe"}, + {file = "multidict-6.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:347eea2852ab7f697cc5ed9b1aae96b08f8529cca0c6468f747f0781b1842898"}, + {file = "multidict-6.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4d3f8e57027dcda84a1aa181501c15c45eab9566eb6fcc274cbd1e7561224f8"}, + {file = "multidict-6.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:9ca57a841ffcf712e47875d026aa49d6e67f9560624d54b51628603700d5d287"}, + {file = "multidict-6.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7cafdafb44c4e646118410368307693e49d19167e5f119cbe3a88697d2d1a636"}, + {file = "multidict-6.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:430120c6ce3715a9c6075cabcee557daccbcca8ba25a9fedf05c7bf564532f2d"}, + {file = "multidict-6.3.2-cp312-cp312-win32.whl", hash = "sha256:13bec31375235a68457ab887ce1bbf4f59d5810d838ae5d7e5b416242e1f3ed4"}, + {file = "multidict-6.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:c3b6d7620e6e90c6d97eaf3a63bf7fbd2ba253aab89120a4a9c660bf2d675391"}, + {file = "multidict-6.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:b9ca24700322816ae0d426aa33671cf68242f8cc85cee0d0e936465ddaee90b5"}, + {file = "multidict-6.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d9fbbe23667d596ff4f9f74d44b06e40ebb0ab6b262cf14a284f859a66f86457"}, + {file = "multidict-6.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9cb602c5bea0589570ad3a4a6f2649c4f13cc7a1e97b4c616e5e9ff8dc490987"}, + {file = "multidict-6.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93ca81dd4d1542e20000ed90f4cc84b7713776f620d04c2b75b8efbe61106c99"}, + {file = "multidict-6.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18b6310b5454c62242577a128c87df8897f39dd913311cf2e1298e47dfc089eb"}, + {file = "multidict-6.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a6dda57de1fc9aedfdb600a8640c99385cdab59a5716cb714b52b6005797f77"}, + {file = "multidict-6.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d8ec42d03cc6b29845552a68151f9e623c541f1708328353220af571e24a247"}, + {file = "multidict-6.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80681969cee2fa84dafeb53615d51d24246849984e3e87fbe4fe39956f2e23bf"}, + {file = "multidict-6.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:01489b0c3592bb9d238e5690e9566db7f77a5380f054b57077d2c4deeaade0eb"}, + {file = "multidict-6.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:522d9f1fd995d04dfedc0a40bca7e2591bc577d920079df50b56245a4a252c1c"}, + {file = "multidict-6.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2014e9cf0b4e9c75bbad49c1758e5a9bf967a56184fc5fcc51527425baf5abba"}, + {file = "multidict-6.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:78ced9fcbee79e446ff4bb3018ac7ba1670703de7873d9c1f6f9883db53c71bc"}, + {file = "multidict-6.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1faf01af972bd01216a107c195f5294f9f393531bc3e4faddc9b333581255d4d"}, + {file = "multidict-6.3.2-cp313-cp313-win32.whl", hash = "sha256:7a699ab13d8d8e1f885de1535b4f477fb93836c87168318244c2685da7b7f655"}, + {file = "multidict-6.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:8666bb0d883310c83be01676e302587834dfd185b52758caeab32ef0eb387bc6"}, + {file = "multidict-6.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:d82c95aabee29612b1c4f48b98be98181686eb7d6c0152301f72715705cc787b"}, + {file = "multidict-6.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f47709173ea9e87a7fd05cd7e5cf1e5d4158924ff988a9a8e0fbd853705f0e68"}, + {file = "multidict-6.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c7f9d0276ceaab41b8ae78534ff28ea33d5de85db551cbf80c44371f2b55d13"}, + {file = "multidict-6.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6eab22df44a25acab2e738f882f5ec551282ab45b2bbda5301e6d2cfb323036"}, + {file = "multidict-6.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a947cb7c657f57874021b9b70c7aac049c877fb576955a40afa8df71d01a1390"}, + {file = "multidict-6.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5faa346e8e1c371187cf345ab1e02a75889f9f510c9cbc575c31b779f7df084d"}, + {file = "multidict-6.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc6e08d977aebf1718540533b4ba5b351ccec2db093370958a653b1f7f9219cc"}, + {file = "multidict-6.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:98eab7acf55275b5bf09834125fa3a80b143a9f241cdcdd3f1295ffdc3c6d097"}, + {file = "multidict-6.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:36863655630becc224375c0b99364978a0f95aebfb27fb6dd500f7fb5fb36e79"}, + {file = "multidict-6.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d9c0979c096c0d46a963331b0e400d3a9e560e41219df4b35f0d7a2f28f39710"}, + {file = "multidict-6.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0efc04f70f05e70e5945890767e8874da5953a196f5b07c552d305afae0f3bf6"}, + {file = "multidict-6.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:2c519b3b82c34539fae3e22e4ea965869ac6b628794b1eb487780dde37637ab7"}, + {file = "multidict-6.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:329160e301f2afd7b43725d3dda8a7ef8ee41d4ceac2083fc0d8c1cc8a4bd56b"}, + {file = "multidict-6.3.2-cp313-cp313t-win32.whl", hash = "sha256:420e5144a5f598dad8db3128f1695cd42a38a0026c2991091dab91697832f8cc"}, + {file = "multidict-6.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:875faded2861c7af2682c67088e6313fec35ede811e071c96d36b081873cea14"}, + {file = "multidict-6.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2516c5eb5732d6c4e29fa93323bfdc55186895124bc569e2404e3820934be378"}, + {file = "multidict-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:be5c8622e665cc5491c13c0fcd52915cdbae991a3514251d71129691338cdfb2"}, + {file = "multidict-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ef33150eea7953cfdb571d862cff894e0ad97ab80d97731eb4b9328fc32d52b"}, + {file = "multidict-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40b357738ce46e998f1b1bad9c4b79b2a9755915f71b87a8c01ce123a22a4f99"}, + {file = "multidict-6.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27c60e059fcd3655a653ba99fec2556cd0260ec57f9cb138d3e6ffc413638a2e"}, + {file = "multidict-6.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:629e7c5e75bde83e54a22c7043ce89d68691d1f103be6d09a1c82b870df3b4b8"}, + {file = "multidict-6.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6c8fc97d893fdf1fff15a619fee8de2f31c9b289ef7594730e35074fa0cefb"}, + {file = "multidict-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52081d2f27e0652265d4637b03f09b82f6da5ce5e1474f07dc64674ff8bfc04c"}, + {file = "multidict-6.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:64529dc395b5fd0a7826ffa70d2d9a7f4abd8f5333d6aaaba67fdf7bedde9f21"}, + {file = "multidict-6.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2b7c3fad827770840f5399348c89635ed6d6e9bba363baad7d3c7f86a9cf1da3"}, + {file = "multidict-6.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:24aa42b1651c654ae9e5273e06c3b7ccffe9f7cc76fbde40c37e9ae65f170818"}, + {file = "multidict-6.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:04ceea01e9991357164b12882e120ce6b4d63a0424bb9f9cd37910aa56d30830"}, + {file = "multidict-6.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:943897a41160945416617db567d867ab34e9258adaffc56a25a4c3f99d919598"}, + {file = "multidict-6.3.2-cp39-cp39-win32.whl", hash = "sha256:76157a9a0c5380aadd3b5ff7b8deee355ff5adecc66c837b444fa633b4d409a2"}, + {file = "multidict-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:d091d123e44035cd5664554308477aff0b58db37e701e7598a67e907b98d1925"}, + {file = "multidict-6.3.2-py3-none-any.whl", hash = "sha256:71409d4579f716217f23be2f5e7afca5ca926aaeb398aa11b72d793bff637a1f"}, + {file = "multidict-6.3.2.tar.gz", hash = "sha256:c1035eea471f759fa853dd6e76aaa1e389f93b3e1403093fa0fd3ab4db490678"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +groups = ["main"] +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "numpy" +version = "1.26.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +markers = "python_version <= \"3.11\"" +files = [ + {file = "numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0"}, + {file = "numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4"}, + {file = "numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a"}, + {file = "numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2"}, + {file = "numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07"}, + {file = "numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71"}, + {file = "numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e"}, + {file = "numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a"}, + {file = "numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a"}, + {file = "numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20"}, + {file = "numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218"}, + {file = "numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b"}, + {file = "numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a"}, + {file = "numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0"}, + {file = "numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110"}, + {file = "numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c"}, + {file = "numpy-1.26.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764"}, + {file = "numpy-1.26.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd"}, + {file = "numpy-1.26.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c"}, + {file = "numpy-1.26.4-cp39-cp39-win32.whl", hash = "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6"}, + {file = "numpy-1.26.4-cp39-cp39-win_amd64.whl", hash = "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c"}, + {file = "numpy-1.26.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0"}, + {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, +] + +[[package]] +name = "numpy" +version = "2.2.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +markers = "python_version >= \"3.12\"" +files = [ + {file = "numpy-2.2.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8146f3550d627252269ac42ae660281d673eb6f8b32f113538e0cc2a9aed42b9"}, + {file = "numpy-2.2.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e642d86b8f956098b564a45e6f6ce68a22c2c97a04f5acd3f221f57b8cb850ae"}, + {file = "numpy-2.2.4-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a84eda42bd12edc36eb5b53bbcc9b406820d3353f1994b6cfe453a33ff101775"}, + {file = "numpy-2.2.4-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:4ba5054787e89c59c593a4169830ab362ac2bee8a969249dc56e5d7d20ff8df9"}, + {file = "numpy-2.2.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7716e4a9b7af82c06a2543c53ca476fa0b57e4d760481273e09da04b74ee6ee2"}, + {file = "numpy-2.2.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:adf8c1d66f432ce577d0197dceaac2ac00c0759f573f28516246351c58a85020"}, + {file = "numpy-2.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:218f061d2faa73621fa23d6359442b0fc658d5b9a70801373625d958259eaca3"}, + {file = "numpy-2.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:df2f57871a96bbc1b69733cd4c51dc33bea66146b8c63cacbfed73eec0883017"}, + {file = "numpy-2.2.4-cp310-cp310-win32.whl", hash = "sha256:a0258ad1f44f138b791327961caedffbf9612bfa504ab9597157806faa95194a"}, + {file = "numpy-2.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:0d54974f9cf14acf49c60f0f7f4084b6579d24d439453d5fc5805d46a165b542"}, + {file = "numpy-2.2.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e9e0a277bb2eb5d8a7407e14688b85fd8ad628ee4e0c7930415687b6564207a4"}, + {file = "numpy-2.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eeea959168ea555e556b8188da5fa7831e21d91ce031e95ce23747b7609f8a4"}, + {file = "numpy-2.2.4-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:bd3ad3b0a40e713fc68f99ecfd07124195333f1e689387c180813f0e94309d6f"}, + {file = "numpy-2.2.4-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cf28633d64294969c019c6df4ff37f5698e8326db68cc2b66576a51fad634880"}, + {file = "numpy-2.2.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fa8fa7697ad1646b5c93de1719965844e004fcad23c91228aca1cf0800044a1"}, + {file = "numpy-2.2.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4162988a360a29af158aeb4a2f4f09ffed6a969c9776f8f3bdee9b06a8ab7e5"}, + {file = "numpy-2.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:892c10d6a73e0f14935c31229e03325a7b3093fafd6ce0af704be7f894d95687"}, + {file = "numpy-2.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db1f1c22173ac1c58db249ae48aa7ead29f534b9a948bc56828337aa84a32ed6"}, + {file = "numpy-2.2.4-cp311-cp311-win32.whl", hash = "sha256:ea2bb7e2ae9e37d96835b3576a4fa4b3a97592fbea8ef7c3587078b0068b8f09"}, + {file = "numpy-2.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91"}, + {file = "numpy-2.2.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a7b9084668aa0f64e64bd00d27ba5146ef1c3a8835f3bd912e7a9e01326804c4"}, + {file = "numpy-2.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dbe512c511956b893d2dacd007d955a3f03d555ae05cfa3ff1c1ff6df8851854"}, + {file = "numpy-2.2.4-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:bb649f8b207ab07caebba230d851b579a3c8711a851d29efe15008e31bb4de24"}, + {file = "numpy-2.2.4-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:f34dc300df798742b3d06515aa2a0aee20941c13579d7a2f2e10af01ae4901ee"}, + {file = "numpy-2.2.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3f7ac96b16955634e223b579a3e5798df59007ca43e8d451a0e6a50f6bfdfba"}, + {file = "numpy-2.2.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f92084defa704deadd4e0a5ab1dc52d8ac9e8a8ef617f3fbb853e79b0ea3592"}, + {file = "numpy-2.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4e84a6283b36632e2a5b56e121961f6542ab886bc9e12f8f9818b3c266bfbb"}, + {file = "numpy-2.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:11c43995255eb4127115956495f43e9343736edb7fcdb0d973defd9de14cd84f"}, + {file = "numpy-2.2.4-cp312-cp312-win32.whl", hash = "sha256:65ef3468b53269eb5fdb3a5c09508c032b793da03251d5f8722b1194f1790c00"}, + {file = "numpy-2.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:2aad3c17ed2ff455b8eaafe06bcdae0062a1db77cb99f4b9cbb5f4ecb13c5146"}, + {file = "numpy-2.2.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cf4e5c6a278d620dee9ddeb487dc6a860f9b199eadeecc567f777daace1e9e7"}, + {file = "numpy-2.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1974afec0b479e50438fc3648974268f972e2d908ddb6d7fb634598cdb8260a0"}, + {file = "numpy-2.2.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:79bd5f0a02aa16808fcbc79a9a376a147cc1045f7dfe44c6e7d53fa8b8a79392"}, + {file = "numpy-2.2.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:3387dd7232804b341165cedcb90694565a6015433ee076c6754775e85d86f1fc"}, + {file = "numpy-2.2.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f527d8fdb0286fd2fd97a2a96c6be17ba4232da346931d967a0630050dfd298"}, + {file = "numpy-2.2.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce43e386c16898b91e162e5baaad90c4b06f9dcbe36282490032cec98dc8ae7"}, + {file = "numpy-2.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31504f970f563d99f71a3512d0c01a645b692b12a63630d6aafa0939e52361e6"}, + {file = "numpy-2.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:81413336ef121a6ba746892fad881a83351ee3e1e4011f52e97fba79233611fd"}, + {file = "numpy-2.2.4-cp313-cp313-win32.whl", hash = "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c"}, + {file = "numpy-2.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:207a2b8441cc8b6a2a78c9ddc64d00d20c303d79fba08c577752f080c4007ee3"}, + {file = "numpy-2.2.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8120575cb4882318c791f839a4fd66161a6fa46f3f0a5e613071aae35b5dd8f8"}, + {file = "numpy-2.2.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a761ba0fa886a7bb33c6c8f6f20213735cb19642c580a931c625ee377ee8bd39"}, + {file = "numpy-2.2.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:ac0280f1ba4a4bfff363a99a6aceed4f8e123f8a9b234c89140f5e894e452ecd"}, + {file = "numpy-2.2.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:879cf3a9a2b53a4672a168c21375166171bc3932b7e21f622201811c43cdd3b0"}, + {file = "numpy-2.2.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f05d4198c1bacc9124018109c5fba2f3201dbe7ab6e92ff100494f236209c960"}, + {file = "numpy-2.2.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f085ce2e813a50dfd0e01fbfc0c12bbe5d2063d99f8b29da30e544fb6483b8"}, + {file = "numpy-2.2.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:92bda934a791c01d6d9d8e038363c50918ef7c40601552a58ac84c9613a665bc"}, + {file = "numpy-2.2.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ee4d528022f4c5ff67332469e10efe06a267e32f4067dc76bb7e2cddf3cd25ff"}, + {file = "numpy-2.2.4-cp313-cp313t-win32.whl", hash = "sha256:05c076d531e9998e7e694c36e8b349969c56eadd2cdcd07242958489d79a7286"}, + {file = "numpy-2.2.4-cp313-cp313t-win_amd64.whl", hash = "sha256:188dcbca89834cc2e14eb2f106c96d6d46f200fe0200310fc29089657379c58d"}, + {file = "numpy-2.2.4-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7051ee569db5fbac144335e0f3b9c2337e0c8d5c9fee015f259a5bd70772b7e8"}, + {file = "numpy-2.2.4-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ab2939cd5bec30a7430cbdb2287b63151b77cf9624de0532d629c9a1c59b1d5c"}, + {file = "numpy-2.2.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0f35b19894a9e08639fd60a1ec1978cb7f5f7f1eace62f38dd36be8aecdef4d"}, + {file = "numpy-2.2.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b4adfbbc64014976d2f91084915ca4e626fbf2057fb81af209c1a6d776d23e3d"}, + {file = "numpy-2.2.4.tar.gz", hash = "sha256:9ba03692a45d3eef66559efe1d1096c4b9b75c0986b5dff5530c378fb8331d4f"}, +] + +[[package]] +name = "orjson" +version = "3.10.16" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "orjson-3.10.16-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4cb473b8e79154fa778fb56d2d73763d977be3dcc140587e07dbc545bbfc38f8"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:622a8e85eeec1948690409a19ca1c7d9fd8ff116f4861d261e6ae2094fe59a00"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c682d852d0ce77613993dc967e90e151899fe2d8e71c20e9be164080f468e370"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c520ae736acd2e32df193bcff73491e64c936f3e44a2916b548da048a48b46b"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:134f87c76bfae00f2094d85cfab261b289b76d78c6da8a7a3b3c09d362fd1e06"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b59afde79563e2cf37cfe62ee3b71c063fd5546c8e662d7fcfc2a3d5031a5c4c"}, + {file = "orjson-3.10.16-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:113602f8241daaff05d6fad25bd481d54c42d8d72ef4c831bb3ab682a54d9e15"}, + {file = "orjson-3.10.16-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4fc0077d101f8fab4031e6554fc17b4c2ad8fdbc56ee64a727f3c95b379e31da"}, + {file = "orjson-3.10.16-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:9c6bf6ff180cd69e93f3f50380224218cfab79953a868ea3908430bcfaf9cb5e"}, + {file = "orjson-3.10.16-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5673eadfa952f95a7cd76418ff189df11b0a9c34b1995dff43a6fdbce5d63bf4"}, + {file = "orjson-3.10.16-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5fe638a423d852b0ae1e1a79895851696cb0d9fa0946fdbfd5da5072d9bb9551"}, + {file = "orjson-3.10.16-cp310-cp310-win32.whl", hash = "sha256:33af58f479b3c6435ab8f8b57999874b4b40c804c7a36b5cc6b54d8f28e1d3dd"}, + {file = "orjson-3.10.16-cp310-cp310-win_amd64.whl", hash = "sha256:0338356b3f56d71293c583350af26f053017071836b07e064e92819ecf1aa055"}, + {file = "orjson-3.10.16-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44fcbe1a1884f8bc9e2e863168b0f84230c3d634afe41c678637d2728ea8e739"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78177bf0a9d0192e0b34c3d78bcff7fe21d1b5d84aeb5ebdfe0dbe637b885225"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:12824073a010a754bb27330cad21d6e9b98374f497f391b8707752b96f72e741"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddd41007e56284e9867864aa2f29f3136bb1dd19a49ca43c0b4eda22a579cf53"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0877c4d35de639645de83666458ca1f12560d9fa7aa9b25d8bb8f52f61627d14"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a09a539e9cc3beead3e7107093b4ac176d015bec64f811afb5965fce077a03c"}, + {file = "orjson-3.10.16-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31b98bc9b40610fec971d9a4d67bb2ed02eec0a8ae35f8ccd2086320c28526ca"}, + {file = "orjson-3.10.16-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0ce243f5a8739f3a18830bc62dc2e05b69a7545bafd3e3249f86668b2bcd8e50"}, + {file = "orjson-3.10.16-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:64792c0025bae049b3074c6abe0cf06f23c8e9f5a445f4bab31dc5ca23dbf9e1"}, + {file = "orjson-3.10.16-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ea53f7e68eec718b8e17e942f7ca56c6bd43562eb19db3f22d90d75e13f0431d"}, + {file = "orjson-3.10.16-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a741ba1a9488c92227711bde8c8c2b63d7d3816883268c808fbeada00400c164"}, + {file = "orjson-3.10.16-cp311-cp311-win32.whl", hash = "sha256:c7ed2c61bb8226384c3fdf1fb01c51b47b03e3f4536c985078cccc2fd19f1619"}, + {file = "orjson-3.10.16-cp311-cp311-win_amd64.whl", hash = "sha256:cd67d8b3e0e56222a2e7b7f7da9031e30ecd1fe251c023340b9f12caca85ab60"}, + {file = "orjson-3.10.16-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6d3444abbfa71ba21bb042caa4b062535b122248259fdb9deea567969140abca"}, + {file = "orjson-3.10.16-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:30245c08d818fdcaa48b7d5b81499b8cae09acabb216fe61ca619876b128e184"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0ba1d0baa71bf7579a4ccdcf503e6f3098ef9542106a0eca82395898c8a500a"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb0beefa5ef3af8845f3a69ff2a4aa62529b5acec1cfe5f8a6b4141033fd46ef"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6daa0e1c9bf2e030e93c98394de94506f2a4d12e1e9dadd7c53d5e44d0f9628e"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9da9019afb21e02410ef600e56666652b73eb3e4d213a0ec919ff391a7dd52aa"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:daeb3a1ee17b69981d3aae30c3b4e786b0f8c9e6c71f2b48f1aef934f63f38f4"}, + {file = "orjson-3.10.16-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80fed80eaf0e20a31942ae5d0728849862446512769692474be5e6b73123a23b"}, + {file = "orjson-3.10.16-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73390ed838f03764540a7bdc4071fe0123914c2cc02fb6abf35182d5fd1b7a42"}, + {file = "orjson-3.10.16-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a22bba012a0c94ec02a7768953020ab0d3e2b884760f859176343a36c01adf87"}, + {file = "orjson-3.10.16-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5385bbfdbc90ff5b2635b7e6bebf259652db00a92b5e3c45b616df75b9058e88"}, + {file = "orjson-3.10.16-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:02c6279016346e774dd92625d46c6c40db687b8a0d685aadb91e26e46cc33e1e"}, + {file = "orjson-3.10.16-cp312-cp312-win32.whl", hash = "sha256:7ca55097a11426db80f79378e873a8c51f4dde9ffc22de44850f9696b7eb0e8c"}, + {file = "orjson-3.10.16-cp312-cp312-win_amd64.whl", hash = "sha256:86d127efdd3f9bf5f04809b70faca1e6836556ea3cc46e662b44dab3fe71f3d6"}, + {file = "orjson-3.10.16-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:148a97f7de811ba14bc6dbc4a433e0341ffd2cc285065199fb5f6a98013744bd"}, + {file = "orjson-3.10.16-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:1d960c1bf0e734ea36d0adc880076de3846aaec45ffad29b78c7f1b7962516b8"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a318cd184d1269f68634464b12871386808dc8b7c27de8565234d25975a7a137"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:df23f8df3ef9223d1d6748bea63fca55aae7da30a875700809c500a05975522b"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b94dda8dd6d1378f1037d7f3f6b21db769ef911c4567cbaa962bb6dc5021cf90"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f12970a26666a8775346003fd94347d03ccb98ab8aa063036818381acf5f523e"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15a1431a245d856bd56e4d29ea0023eb4d2c8f71efe914beb3dee8ab3f0cd7fb"}, + {file = "orjson-3.10.16-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c83655cfc247f399a222567d146524674a7b217af7ef8289c0ff53cfe8db09f0"}, + {file = "orjson-3.10.16-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fa59ae64cb6ddde8f09bdbf7baf933c4cd05734ad84dcf4e43b887eb24e37652"}, + {file = "orjson-3.10.16-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ca5426e5aacc2e9507d341bc169d8af9c3cbe88f4cd4c1cf2f87e8564730eb56"}, + {file = "orjson-3.10.16-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6fd5da4edf98a400946cd3a195680de56f1e7575109b9acb9493331047157430"}, + {file = "orjson-3.10.16-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:980ecc7a53e567169282a5e0ff078393bac78320d44238da4e246d71a4e0e8f5"}, + {file = "orjson-3.10.16-cp313-cp313-win32.whl", hash = "sha256:28f79944dd006ac540a6465ebd5f8f45dfdf0948ff998eac7a908275b4c1add6"}, + {file = "orjson-3.10.16-cp313-cp313-win_amd64.whl", hash = "sha256:fe0a145e96d51971407cb8ba947e63ead2aa915db59d6631a355f5f2150b56b7"}, + {file = "orjson-3.10.16-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c35b5c1fb5a5d6d2fea825dec5d3d16bea3c06ac744708a8e1ff41d4ba10cdf1"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9aac7ecc86218b4b3048c768f227a9452287001d7548500150bb75ee21bf55d"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6e19f5102fff36f923b6dfdb3236ec710b649da975ed57c29833cb910c5a73ab"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17210490408eb62755a334a6f20ed17c39f27b4f45d89a38cd144cd458eba80b"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fbbe04451db85916e52a9f720bd89bf41f803cf63b038595674691680cbebd1b"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a966eba501a3a1f309f5a6af32ed9eb8f316fa19d9947bac3e6350dc63a6f0a"}, + {file = "orjson-3.10.16-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01e0d22f06c81e6c435723343e1eefc710e0510a35d897856766d475f2a15687"}, + {file = "orjson-3.10.16-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7c1e602d028ee285dbd300fb9820b342b937df64d5a3336e1618b354e95a2569"}, + {file = "orjson-3.10.16-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:d230e5020666a6725629df81e210dc11c3eae7d52fe909a7157b3875238484f3"}, + {file = "orjson-3.10.16-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0f8baac07d4555f57d44746a7d80fbe6b2c4fe2ed68136b4abb51cfec512a5e9"}, + {file = "orjson-3.10.16-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:524e48420b90fc66953e91b660b3d05faaf921277d6707e328fde1c218b31250"}, + {file = "orjson-3.10.16-cp39-cp39-win32.whl", hash = "sha256:a9f614e31423d7292dbca966a53b2d775c64528c7d91424ab2747d8ab8ce5c72"}, + {file = "orjson-3.10.16-cp39-cp39-win_amd64.whl", hash = "sha256:c338dc2296d1ed0d5c5c27dfb22d00b330555cb706c2e0be1e1c3940a0895905"}, + {file = "orjson-3.10.16.tar.gz", hash = "sha256:d2aaa5c495e11d17b9b93205f5fa196737ee3202f000aaebf028dc9a73750f10"}, +] + +[[package]] +name = "ormsgpack" +version = "1.9.1" +description = "Fast, correct Python msgpack library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "ormsgpack-1.9.1-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:f1f804fd9c0fd84213a6022c34172f82323b34afa7052a4af18797582cf56365"}, + {file = "ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eab5cec99c46276b37071d570aab98603f3d0309b3818da3247eb64bb95e5cfc"}, + {file = "ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1c12c6bb30e6df6fc0213b77f0a5e143f371d618be2e8eb4d555340ce01c6900"}, + {file = "ormsgpack-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:994d4bbb7ee333264a3e55e30ccee063df6635d785f21a08bf52f67821454a51"}, + {file = "ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a668a584cf4bb6e1a6ef5a35f3f0d0fdae80cfb7237344ad19a50cce8c79317b"}, + {file = "ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:aaf77699203822638014c604d100f132583844d4fd01eb639a2266970c02cfdf"}, + {file = "ormsgpack-1.9.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:003d7e1992b447898caf25a820b3037ec68a57864b3e2f34b64693b7d60a9984"}, + {file = "ormsgpack-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:67fefc77e4ba9469f79426769eb4c78acf21f22bef3ab1239a72dd728036ffc2"}, + {file = "ormsgpack-1.9.1-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:16eaf32c33ab4249e242181d59e2509b8e0330d6f65c1d8bf08c3dea38fd7c02"}, + {file = "ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c70f2e5b2f9975536e8f7936a9721601dc54febe363d2d82f74c9b31d4fe1c65"}, + {file = "ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:17c9e18b07d69e3db2e0f8af4731040175e11bdfde78ad8e28126e9e66ec5167"}, + {file = "ormsgpack-1.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73538d749096bb6470328601a2be8f7bdec28849ec6fd19595c232a5848d7124"}, + {file = "ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:827ff71de228cfd6d07b9d6b47911aa61b1e8dc995dec3caf8fdcdf4f874bcd0"}, + {file = "ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:7307f808b3df282c8e8ed92c6ebceeb3eea3d8eeec808438f3f212226b25e217"}, + {file = "ormsgpack-1.9.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f30aad7fb083bed1c540a3c163c6a9f63a94e3c538860bf8f13386c29b560ad5"}, + {file = "ormsgpack-1.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:829a1b4c5bc3c38ece0c55cf91ebc09c3b987fceb24d3f680c2bcd03fd3789a4"}, + {file = "ormsgpack-1.9.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1ede445fc3fdba219bb0e0d1f289df26a9c7602016b7daac6fafe8fe4e91548f"}, + {file = "ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db50b9f918e25b289114312ed775794d0978b469831b992bdc65bfe20b91fe30"}, + {file = "ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8c7d8fc58e4333308f58ec720b1ee6b12b2b3fe2d2d8f0766ab751cb351e8757"}, + {file = "ormsgpack-1.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeee6d08c040db265cb8563444aba343ecb32cbdbe2414a489dcead9f70c6765"}, + {file = "ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2fbb8181c198bdc413a4e889e5200f010724eea4b6d5a9a7eee2df039ac04aca"}, + {file = "ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:16488f094ac0e2250cceea6caf72962614aa432ee11dd57ef45e1ad25ece3eff"}, + {file = "ormsgpack-1.9.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:422d960bfd6ad88be20794f50ec7953d8f7a0f2df60e19d0e8feb994e2ed64ee"}, + {file = "ormsgpack-1.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:e6e2f9eab527cf43fb4a4293e493370276b1c8716cf305689202d646c6a782ef"}, + {file = "ormsgpack-1.9.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ac61c18d9dd085e8519b949f7e655f7fb07909fd09c53b4338dd33309012e289"}, + {file = "ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134840b8c6615da2c24ce77bd12a46098015c808197a9995c7a2d991e1904eec"}, + {file = "ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38fd42618f626394b2c7713c5d4bcbc917254e9753d5d4cde460658b51b11a74"}, + {file = "ormsgpack-1.9.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d36397333ad07b9eba4c2e271fa78951bd81afc059c85a6e9f6c0eb2de07cda"}, + {file = "ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:603063089597917d04e4c1b1d53988a34f7dc2ff1a03adcfd1cf4ae966d5fba6"}, + {file = "ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:94bbf2b185e0cb721ceaba20e64b7158e6caf0cecd140ca29b9f05a8d5e91e2f"}, + {file = "ormsgpack-1.9.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c38f380b1e8c96a712eb302b9349347385161a8e29046868ae2bfdfcb23e2692"}, + {file = "ormsgpack-1.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:a4bc63fb30db94075611cedbbc3d261dd17cf2aa8ff75a0fd684cd45ca29cb1b"}, + {file = "ormsgpack-1.9.1-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e95909248bece8e88a310a913838f17ff5a39190aa4e61de909c3cd27f59744b"}, + {file = "ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3939188810c5c641d6b207f29994142ae2b1c70534f7839bbd972d857ac2072"}, + {file = "ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b6476344a585aea00a2acc9fd07355bf2daac04062cfdd480fa83ec3e2403b"}, + {file = "ormsgpack-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7d8b9d53da82b31662ce5a3834b65479cf794a34befb9fc50baa51518383250"}, + {file = "ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3933d4b0c0d404ee234dbc372836d6f2d2f4b6330c2a2fb9709ba4eaebfae7ba"}, + {file = "ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:f824e94a7969f0aee9a6847ec232cf731a03b8734951c2a774dd4762308ea2d2"}, + {file = "ormsgpack-1.9.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c1f3f2295374020f9650e4aa7af6403ff016a0d92778b4a48bb3901fd801232d"}, + {file = "ormsgpack-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:92eb1b4f7b168da47f547329b4b58d16d8f19508a97ce5266567385d42d81968"}, + {file = "ormsgpack-1.9.1.tar.gz", hash = "sha256:3da6e63d82565e590b98178545e64f0f8506137b92bd31a2d04fd7c82baf5794"}, +] + +[[package]] +name = "packaging" +version = "24.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, + {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" +groups = ["main"] +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.23.2", markers = "python_version == \"3.11\""}, + {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" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "propcache" +version = "0.3.1" +description = "Accelerated property cache" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f27785888d2fdd918bc36de8b8739f2d6c791399552333721b58193f68ea3e98"}, + {file = "propcache-0.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4e89cde74154c7b5957f87a355bb9c8ec929c167b59c83d90654ea36aeb6180"}, + {file = "propcache-0.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:730178f476ef03d3d4d255f0c9fa186cb1d13fd33ffe89d39f2cda4da90ceb71"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:967a8eec513dbe08330f10137eacb427b2ca52118769e82ebcfcab0fba92a649"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b9145c35cc87313b5fd480144f8078716007656093d23059e8993d3a8fa730f"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e64e948ab41411958670f1093c0a57acfdc3bee5cf5b935671bbd5313bcf229"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319fa8765bfd6a265e5fa661547556da381e53274bc05094fc9ea50da51bfd46"}, + {file = "propcache-0.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66d8ccbc902ad548312b96ed8d5d266d0d2c6d006fd0f66323e9d8f2dd49be7"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2d219b0dbabe75e15e581fc1ae796109b07c8ba7d25b9ae8d650da582bed01b0"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cd6a55f65241c551eb53f8cf4d2f4af33512c39da5d9777694e9d9c60872f519"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9979643ffc69b799d50d3a7b72b5164a2e97e117009d7af6dfdd2ab906cb72cd"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cf9e93a81979f1424f1a3d155213dc928f1069d697e4353edb8a5eba67c6259"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2fce1df66915909ff6c824bbb5eb403d2d15f98f1518e583074671a30fe0c21e"}, + {file = "propcache-0.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4d0dfdd9a2ebc77b869a0b04423591ea8823f791293b527dc1bb896c1d6f1136"}, + {file = "propcache-0.3.1-cp310-cp310-win32.whl", hash = "sha256:1f6cc0ad7b4560e5637eb2c994e97b4fa41ba8226069c9277eb5ea7101845b42"}, + {file = "propcache-0.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:47ef24aa6511e388e9894ec16f0fbf3313a53ee68402bc428744a367ec55b833"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371"}, + {file = "propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256"}, + {file = "propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a"}, + {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9"}, + {file = "propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005"}, + {file = "propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976"}, + {file = "propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25"}, + {file = "propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5"}, + {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7"}, + {file = "propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b"}, + {file = "propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f"}, + {file = "propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120"}, + {file = "propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7"}, + {file = "propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef"}, + {file = "propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24"}, + {file = "propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c"}, + {file = "propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458"}, + {file = "propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18"}, + {file = "propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a"}, + {file = "propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d"}, + {file = "propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ed5f6d2edbf349bd8d630e81f474d33d6ae5d07760c44d33cd808e2f5c8f4ae6"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:668ddddc9f3075af019f784456267eb504cb77c2c4bd46cc8402d723b4d200bf"}, + {file = "propcache-0.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c86e7ceea56376216eba345aa1fc6a8a6b27ac236181f840d1d7e6a1ea9ba5c"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83be47aa4e35b87c106fc0c84c0fc069d3f9b9b06d3c494cd404ec6747544894"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27c6ac6aa9fc7bc662f594ef380707494cb42c22786a558d95fcdedb9aa5d035"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a956dff37080b352c1c40b2966b09defb014347043e740d420ca1eb7c9b908"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82de5da8c8893056603ac2d6a89eb8b4df49abf1a7c19d536984c8dd63f481d5"}, + {file = "propcache-0.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c3c3a203c375b08fd06a20da3cf7aac293b834b6f4f4db71190e8422750cca5"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b303b194c2e6f171cfddf8b8ba30baefccf03d36a4d9cab7fd0bb68ba476a3d7"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:916cd229b0150129d645ec51614d38129ee74c03293a9f3f17537be0029a9641"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a461959ead5b38e2581998700b26346b78cd98540b5524796c175722f18b0294"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:069e7212890b0bcf9b2be0a03afb0c2d5161d91e1bf51569a64f629acc7defbf"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef2e4e91fb3945769e14ce82ed53007195e616a63aa43b40fb7ebaaf907c8d4c"}, + {file = "propcache-0.3.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8638f99dca15b9dff328fb6273e09f03d1c50d9b6512f3b65a4154588a7595fe"}, + {file = "propcache-0.3.1-cp39-cp39-win32.whl", hash = "sha256:6f173bbfe976105aaa890b712d1759de339d8a7cef2fc0a1714cc1a1e1c47f64"}, + {file = "propcache-0.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:603f1fe4144420374f1a69b907494c3acbc867a581c2d49d4175b0de7cc64566"}, + {file = "propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40"}, + {file = "propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf"}, +] + +[[package]] +name = "psycopg2-binary" +version = "2.9.10" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win32.whl", hash = "sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "platform_python_implementation == \"PyPy\"" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pydantic" +version = "2.11.2" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pydantic-2.11.2-py3-none-any.whl", hash = "sha256:7f17d25846bcdf89b670a86cdfe7b29a9f1c9ca23dee154221c9aa81845cfca7"}, + {file = "pydantic-2.11.2.tar.gz", hash = "sha256:2138628e050bd7a1e70b91d4bf4a91167f4ad76fdb83209b107c8d84b854917e"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.33.1" +typing-extensions = ">=4.12.2" +typing-inspection = ">=0.4.0" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] + +[[package]] +name = "pydantic-core" +version = "2.33.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pydantic_core-2.33.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3077cfdb6125cc8dab61b155fdd714663e401f0e6883f9632118ec12cf42df26"}, + {file = "pydantic_core-2.33.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ffab8b2908d152e74862d276cf5017c81a2f3719f14e8e3e8d6b83fda863927"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5183e4f6a2d468787243ebcd70cf4098c247e60d73fb7d68d5bc1e1beaa0c4db"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:398a38d323f37714023be1e0285765f0a27243a8b1506b7b7de87b647b517e48"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3776f0001b43acebfa86f8c64019c043b55cc5a6a2e313d728b5c95b46969"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c566dd9c5f63d22226409553531f89de0cac55397f2ab8d97d6f06cfce6d947e"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0d5f3acc81452c56895e90643a625302bd6be351e7010664151cc55b7b97f89"}, + {file = "pydantic_core-2.33.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d3a07fadec2a13274a8d861d3d37c61e97a816beae717efccaa4b36dfcaadcde"}, + {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f99aeda58dce827f76963ee87a0ebe75e648c72ff9ba1174a253f6744f518f65"}, + {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:902dbc832141aa0ec374f4310f1e4e7febeebc3256f00dc359a9ac3f264a45dc"}, + {file = "pydantic_core-2.33.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fe44d56aa0b00d66640aa84a3cbe80b7a3ccdc6f0b1ca71090696a6d4777c091"}, + {file = "pydantic_core-2.33.1-cp310-cp310-win32.whl", hash = "sha256:ed3eb16d51257c763539bde21e011092f127a2202692afaeaccb50db55a31383"}, + {file = "pydantic_core-2.33.1-cp310-cp310-win_amd64.whl", hash = "sha256:694ad99a7f6718c1a498dc170ca430687a39894a60327f548e02a9c7ee4b6504"}, + {file = "pydantic_core-2.33.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6e966fc3caaf9f1d96b349b0341c70c8d6573bf1bac7261f7b0ba88f96c56c24"}, + {file = "pydantic_core-2.33.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bfd0adeee563d59c598ceabddf2c92eec77abcb3f4a391b19aa7366170bd9e30"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91815221101ad3c6b507804178a7bb5cb7b2ead9ecd600041669c8d805ebd595"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9fea9c1869bb4742d174a57b4700c6dadea951df8b06de40c2fedb4f02931c2e"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d20eb4861329bb2484c021b9d9a977566ab16d84000a57e28061151c62b349a"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb935c5591573ae3201640579f30128ccc10739b45663f93c06796854405505"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c964fd24e6166420d18fb53996d8c9fd6eac9bf5ae3ec3d03015be4414ce497f"}, + {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:681d65e9011f7392db5aa002b7423cc442d6a673c635668c227c6c8d0e5a4f77"}, + {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e100c52f7355a48413e2999bfb4e139d2977a904495441b374f3d4fb4a170961"}, + {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:048831bd363490be79acdd3232f74a0e9951b11b2b4cc058aeb72b22fdc3abe1"}, + {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bdc84017d28459c00db6f918a7272a5190bec3090058334e43a76afb279eac7c"}, + {file = "pydantic_core-2.33.1-cp311-cp311-win32.whl", hash = "sha256:32cd11c5914d1179df70406427097c7dcde19fddf1418c787540f4b730289896"}, + {file = "pydantic_core-2.33.1-cp311-cp311-win_amd64.whl", hash = "sha256:2ea62419ba8c397e7da28a9170a16219d310d2cf4970dbc65c32faf20d828c83"}, + {file = "pydantic_core-2.33.1-cp311-cp311-win_arm64.whl", hash = "sha256:fc903512177361e868bc1f5b80ac8c8a6e05fcdd574a5fb5ffeac5a9982b9e89"}, + {file = "pydantic_core-2.33.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1293d7febb995e9d3ec3ea09caf1a26214eec45b0f29f6074abb004723fc1de8"}, + {file = "pydantic_core-2.33.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99b56acd433386c8f20be5c4000786d1e7ca0523c8eefc995d14d79c7a081498"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35a5ec3fa8c2fe6c53e1b2ccc2454398f95d5393ab398478f53e1afbbeb4d939"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b172f7b9d2f3abc0efd12e3386f7e48b576ef309544ac3a63e5e9cdd2e24585d"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9097b9f17f91eea659b9ec58148c0747ec354a42f7389b9d50701610d86f812e"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc77ec5b7e2118b152b0d886c7514a4653bcb58c6b1d760134a9fab915f777b3"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3d15245b08fa4a84cefc6c9222e6f37c98111c8679fbd94aa145f9a0ae23d"}, + {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef99779001d7ac2e2461d8ab55d3373fe7315caefdbecd8ced75304ae5a6fc6b"}, + {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fc6bf8869e193855e8d91d91f6bf59699a5cdfaa47a404e278e776dd7f168b39"}, + {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:b1caa0bc2741b043db7823843e1bde8aaa58a55a58fda06083b0569f8b45693a"}, + {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ec259f62538e8bf364903a7d0d0239447059f9434b284f5536e8402b7dd198db"}, + {file = "pydantic_core-2.33.1-cp312-cp312-win32.whl", hash = "sha256:e14f369c98a7c15772b9da98987f58e2b509a93235582838bd0d1d8c08b68fda"}, + {file = "pydantic_core-2.33.1-cp312-cp312-win_amd64.whl", hash = "sha256:1c607801d85e2e123357b3893f82c97a42856192997b95b4d8325deb1cd0c5f4"}, + {file = "pydantic_core-2.33.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d13f0276806ee722e70a1c93da19748594f19ac4299c7e41237fc791d1861ea"}, + {file = "pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a"}, + {file = "pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d"}, + {file = "pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4"}, + {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde"}, + {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e"}, + {file = "pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd"}, + {file = "pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f"}, + {file = "pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40"}, + {file = "pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523"}, + {file = "pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d"}, + {file = "pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c"}, + {file = "pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18"}, + {file = "pydantic_core-2.33.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5ab77f45d33d264de66e1884fca158bc920cb5e27fd0764a72f72f5756ae8bdb"}, + {file = "pydantic_core-2.33.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7aaba1b4b03aaea7bb59e1b5856d734be011d3e6d98f5bcaa98cb30f375f2ad"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fb66263e9ba8fea2aa85e1e5578980d127fb37d7f2e292773e7bc3a38fb0c7b"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f2648b9262607a7fb41d782cc263b48032ff7a03a835581abbf7a3bec62bcf5"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:723c5630c4259400818b4ad096735a829074601805d07f8cafc366d95786d331"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d100e3ae783d2167782391e0c1c7a20a31f55f8015f3293647544df3f9c67824"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177d50460bc976a0369920b6c744d927b0ecb8606fb56858ff542560251b19e5"}, + {file = "pydantic_core-2.33.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3edde68d1a1f9af1273b2fe798997b33f90308fb6d44d8550c89fc6a3647cf6"}, + {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a62c3c3ef6a7e2c45f7853b10b5bc4ddefd6ee3cd31024754a1a5842da7d598d"}, + {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:c91dbb0ab683fa0cd64a6e81907c8ff41d6497c346890e26b23de7ee55353f96"}, + {file = "pydantic_core-2.33.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f466e8bf0a62dc43e068c12166281c2eca72121dd2adc1040f3aa1e21ef8599"}, + {file = "pydantic_core-2.33.1-cp39-cp39-win32.whl", hash = "sha256:ab0277cedb698749caada82e5d099dc9fed3f906a30d4c382d1a21725777a1e5"}, + {file = "pydantic_core-2.33.1-cp39-cp39-win_amd64.whl", hash = "sha256:5773da0ee2d17136b1f1c6fbde543398d452a6ad2a7b54ea1033e2daa739b8d2"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c834f54f8f4640fd7e4b193f80eb25a0602bba9e19b3cd2fc7ffe8199f5ae02"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:049e0de24cf23766f12cc5cc71d8abc07d4a9deb9061b334b62093dedc7cb068"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a28239037b3d6f16916a4c831a5a0eadf856bdd6d2e92c10a0da3a59eadcf3e"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d3da303ab5f378a268fa7d45f37d7d85c3ec19769f28d2cc0c61826a8de21fe"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25626fb37b3c543818c14821afe0fd3830bc327a43953bc88db924b68c5723f1"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3ab2d36e20fbfcce8f02d73c33a8a7362980cff717926bbae030b93ae46b56c7"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:2f9284e11c751b003fd4215ad92d325d92c9cb19ee6729ebd87e3250072cdcde"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:048c01eee07d37cbd066fc512b9d8b5ea88ceeb4e629ab94b3e56965ad655add"}, + {file = "pydantic_core-2.33.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5ccd429694cf26af7997595d627dd2637e7932214486f55b8a357edaac9dae8c"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a371dc00282c4b84246509a5ddc808e61b9864aa1eae9ecc92bb1268b82db4a"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f59295ecc75a1788af8ba92f2e8c6eeaa5a94c22fc4d151e8d9638814f85c8fc"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08530b8ac922003033f399128505f513e30ca770527cc8bbacf75a84fcc2c74b"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae370459da6a5466978c0eacf90690cb57ec9d533f8e63e564ef3822bfa04fe"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e3de2777e3b9f4d603112f78006f4ae0acb936e95f06da6cb1a45fbad6bdb4b5"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a64e81e8cba118e108d7126362ea30e021291b7805d47e4896e52c791be2761"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:52928d8c1b6bda03cc6d811e8923dffc87a2d3c8b3bfd2ce16471c7147a24850"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1b30d92c9412beb5ac6b10a3eb7ef92ccb14e3f2a8d7732e2d739f58b3aa7544"}, + {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f995719707e0e29f0f41a8aa3bcea6e761a36c9136104d3189eafb83f5cec5e5"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7edbc454a29fc6aeae1e1eecba4f07b63b8d76e76a748532233c4c167b4cb9ea"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad05b683963f69a1d5d2c2bdab1274a31221ca737dbbceaa32bcb67359453cdd"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df6a94bf9452c6da9b5d76ed229a5683d0306ccb91cca8e1eea883189780d568"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7965c13b3967909a09ecc91f21d09cfc4576bf78140b988904e94f130f188396"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3f1fdb790440a34f6ecf7679e1863b825cb5ffde858a9197f851168ed08371e5"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5277aec8d879f8d05168fdd17ae811dd313b8ff894aeeaf7cd34ad28b4d77e33"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:8ab581d3530611897d863d1a649fb0644b860286b4718db919bfd51ece41f10b"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0483847fa9ad5e3412265c1bd72aad35235512d9ce9d27d81a56d935ef489672"}, + {file = "pydantic_core-2.33.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:de9e06abe3cc5ec6a2d5f75bc99b0bdca4f5c719a5b34026f8c57efbdecd2ee3"}, + {file = "pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pydantic-settings" +version = "2.8.1" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c"}, + {file = "pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585"}, +] + +[package.dependencies] +pydantic = ">=2.7.0" +python-dotenv = ">=0.21.0" + +[package.extras] +azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0)"] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "pytest" +version = "8.3.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, + {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, +] + +[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 = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-dotenv" +version = "1.1.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d"}, + {file = "python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + +[[package]] +name = "pytz" +version = "2025.2" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"}, + {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +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 = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.40" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "SQLAlchemy-2.0.40-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ae9597cab738e7cc823f04a704fb754a9249f0b6695a6aeb63b74055cd417a96"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a5c21ab099a83d669ebb251fddf8f5cee4d75ea40a5a1653d9c43d60e20867"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bece9527f5a98466d67fb5d34dc560c4da964240d8b09024bb21c1246545e04e"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:8bb131ffd2165fae48162c7bbd0d97c84ab961deea9b8bab16366543deeab625"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9408fd453d5f8990405cc9def9af46bfbe3183e6110401b407c2d073c3388f47"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win32.whl", hash = "sha256:00a494ea6f42a44c326477b5bee4e0fc75f6a80c01570a32b57e89cf0fbef85a"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win_amd64.whl", hash = "sha256:c7b927155112ac858357ccf9d255dd8c044fd9ad2dc6ce4c4149527c901fa4c3"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1ea21bef99c703f44444ad29c2c1b6bd55d202750b6de8e06a955380f4725d7"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:afe63b208153f3a7a2d1a5b9df452b0673082588933e54e7c8aac457cf35e758"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8aae085ea549a1eddbc9298b113cffb75e514eadbb542133dd2b99b5fb3b6af"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ea9181284754d37db15156eb7be09c86e16e50fbe77610e9e7bee09291771a1"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5434223b795be5c5ef8244e5ac98056e290d3a99bdcc539b916e282b160dda00"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15d08d5ef1b779af6a0909b97be6c1fd4298057504eb6461be88bd1696cb438e"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win32.whl", hash = "sha256:cd2f75598ae70bcfca9117d9e51a3b06fe29edd972fdd7fd57cc97b4dbf3b08a"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win_amd64.whl", hash = "sha256:2cbafc8d39ff1abdfdda96435f38fab141892dc759a2165947d1a8fffa7ef596"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6bacab7514de6146a1976bc56e1545bee247242fab030b89e5f70336fc0003e"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5654d1ac34e922b6c5711631f2da497d3a7bffd6f9f87ac23b35feea56098011"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35904d63412db21088739510216e9349e335f142ce4a04b69e2528020ee19ed4"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7a80ed86d6aaacb8160a1caef6680d4ddd03c944d985aecee940d168c411d1"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:519624685a51525ddaa7d8ba8265a1540442a2ec71476f0e75241eb8263d6f51"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5f9999a5b0e9689bed96e60ee53c3384f1a05c2dd8068cc2e8361b0df5b7a"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win32.whl", hash = "sha256:c0cae71e20e3c02c52f6b9e9722bca70e4a90a466d59477822739dc31ac18b4b"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win_amd64.whl", hash = "sha256:574aea2c54d8f1dd1699449f332c7d9b71c339e04ae50163a3eb5ce4c4325ee4"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9d3b31d0a1c44b74d3ae27a3de422dfccd2b8f0b75e51ecb2faa2bf65ab1ba0d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f7a0f506cf78c80450ed1e816978643d3969f99c4ac6b01104a6fe95c5490a"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb933a650323e476a2e4fbef8997a10d0003d4da996aad3fd7873e962fdde4d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6959738971b4745eea16f818a2cd086fb35081383b078272c35ece2b07012716"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:110179728e442dae85dd39591beb74072ae4ad55a44eda2acc6ec98ead80d5f2"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8040680eaacdce4d635f12c55c714f3d4c7f57da2bc47a01229d115bd319191"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win32.whl", hash = "sha256:650490653b110905c10adac69408380688cefc1f536a137d0d69aca1069dc1d1"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win_amd64.whl", hash = "sha256:2be94d75ee06548d2fc591a3513422b873490efb124048f50556369a834853b0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50f5885bbed261fc97e2e66c5156244f9704083a674b8d17f24c72217d29baf5"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf0e99cdb600eabcd1d65cdba0d3c91418fee21c4aa1d28db47d095b1064a7d8"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe147fcd85aaed53ce90645c91ed5fca0cc88a797314c70dfd9d35925bd5d106"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf7cee56bd552385c1ee39af360772fbfc2f43be005c78d1140204ad6148438"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4aeb939bcac234b88e2d25d5381655e8353fe06b4e50b1c55ecffe56951d18c2"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c268b5100cfeaa222c40f55e169d484efa1384b44bf9ca415eae6d556f02cb08"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win32.whl", hash = "sha256:46628ebcec4f23a1584fb52f2abe12ddb00f3bb3b7b337618b80fc1b51177aff"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win_amd64.whl", hash = "sha256:7e0505719939e52a7b0c65d20e84a6044eb3712bb6f239c6b1db77ba8e173a37"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c884de19528e0fcd9dc34ee94c810581dd6e74aef75437ff17e696c2bfefae3e"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1abb387710283fc5983d8a1209d9696a4eae9db8d7ac94b402981fe2fe2e39ad"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cfa124eda500ba4b0d3afc3e91ea27ed4754e727c7f025f293a22f512bcd4c9"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6b28d303b9d57c17a5164eb1fd2d5119bb6ff4413d5894e74873280483eeb5"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5a5bbe29c10c5bfd63893747a1bf6f8049df607638c786252cb9243b86b6706"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f0fda83e113bb0fb27dc003685f32a5dcb99c9c4f41f4fa0838ac35265c23b5c"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win32.whl", hash = "sha256:957f8d85d5e834397ef78a6109550aeb0d27a53b5032f7a57f2451e1adc37e98"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win_amd64.whl", hash = "sha256:1ffdf9c91428e59744f8e6f98190516f8e1d05eec90e936eb08b257332c5e870"}, + {file = "sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a"}, + {file = "sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00"}, +] + +[package.dependencies] +greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] +aioodbc = ["aioodbc", "greenlet (>=1)"] +aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (>=1)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] + +[package.extras] +widechars = ["wcwidth"] + +[[package]] +name = "tenacity" +version = "9.1.2" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138"}, + {file = "tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb"}, +] + +[package.extras] +doc = ["reno", "sphinx"] +test = ["pytest", "tornado (>=4.5)", "typeguard"] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["main"] +markers = "python_version < \"3.11\"" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "typing-extensions" +version = "4.13.1" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "typing_extensions-4.13.1-py3-none-any.whl", hash = "sha256:4b6cf02909eb5495cfbc3f6e8fd49217e6cc7944e145cdda8caa3734777f9e69"}, + {file = "typing_extensions-4.13.1.tar.gz", hash = "sha256:98795af00fb9640edec5b8e31fc647597b4691f099ad75f469a2616be1a76dff"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "typing-inspection" +version = "0.4.0" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, + {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + +[[package]] +name = "tzdata" +version = "2025.2" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +groups = ["main"] +files = [ + {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, + {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, +] + +[[package]] +name = "urllib3" +version = "2.1.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "yarl" +version = "1.18.3" +description = "Yet another URL library" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, + {file = "yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc"}, + {file = "yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b"}, + {file = "yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690"}, + {file = "yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6"}, + {file = "yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193"}, + {file = "yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae"}, + {file = "yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e"}, + {file = "yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a"}, + {file = "yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1"}, + {file = "yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576"}, + {file = "yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba"}, + {file = "yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393"}, + {file = "yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285"}, + {file = "yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2"}, + {file = "yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa"}, + {file = "yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58"}, + {file = "yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10"}, + {file = "yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8"}, + {file = "yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d"}, + {file = "yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61e5e68cb65ac8f547f6b5ef933f510134a6bf31bb178be428994b0cb46c2a04"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fe57328fbc1bfd0bd0514470ac692630f3901c0ee39052ae47acd1d90a436719"}, + {file = "yarl-1.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a440a2a624683108a1b454705ecd7afc1c3438a08e890a1513d468671d90a04e"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09c7907c8548bcd6ab860e5f513e727c53b4a714f459b084f6580b49fa1b9cee"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4f6450109834af88cb4cc5ecddfc5380ebb9c228695afc11915a0bf82116789"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9ca04806f3be0ac6d558fffc2fdf8fcef767e0489d2684a21912cc4ed0cd1b8"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77a6e85b90a7641d2e07184df5557132a337f136250caafc9ccaa4a2a998ca2c"}, + {file = "yarl-1.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6333c5a377c8e2f5fae35e7b8f145c617b02c939d04110c76f29ee3676b5f9a5"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0b3c92fa08759dbf12b3a59579a4096ba9af8dd344d9a813fc7f5070d86bbab1"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:4ac515b860c36becb81bb84b667466885096b5fc85596948548b667da3bf9f24"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:045b8482ce9483ada4f3f23b3774f4e1bf4f23a2d5c912ed5170f68efb053318"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a4bb030cf46a434ec0225bddbebd4b89e6471814ca851abb8696170adb163985"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:54d6921f07555713b9300bee9c50fb46e57e2e639027089b1d795ecd9f7fa910"}, + {file = "yarl-1.18.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1d407181cfa6e70077df3377938c08012d18893f9f20e92f7d2f314a437c30b1"}, + {file = "yarl-1.18.3-cp39-cp39-win32.whl", hash = "sha256:ac36703a585e0929b032fbaab0707b75dc12703766d0b53486eabd5139ebadd5"}, + {file = "yarl-1.18.3-cp39-cp39-win_amd64.whl", hash = "sha256:ba87babd629f8af77f557b61e49e7c7cac36f22f871156b91e10a6e9d4f829e9"}, + {file = "yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b"}, + {file = "yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" +propcache = ">=0.2.0" + +[[package]] +name = "zstandard" +version = "0.23.0" +description = "Zstandard bindings for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "zstandard-0.23.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf0a05b6059c0528477fba9054d09179beb63744355cab9f38059548fedd46a9"}, + {file = "zstandard-0.23.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc9ca1c9718cb3b06634c7c8dec57d24e9438b2aa9a0f02b8bb36bf478538880"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77da4c6bfa20dd5ea25cbf12c76f181a8e8cd7ea231c673828d0386b1740b8dc"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2170c7e0367dde86a2647ed5b6f57394ea7f53545746104c6b09fc1f4223573"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c16842b846a8d2a145223f520b7e18b57c8f476924bda92aeee3a88d11cfc391"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:157e89ceb4054029a289fb504c98c6a9fe8010f1680de0201b3eb5dc20aa6d9e"}, + {file = "zstandard-0.23.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:203d236f4c94cd8379d1ea61db2fce20730b4c38d7f1c34506a31b34edc87bdd"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dc5d1a49d3f8262be192589a4b72f0d03b72dcf46c51ad5852a4fdc67be7b9e4"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:752bf8a74412b9892f4e5b58f2f890a039f57037f52c89a740757ebd807f33ea"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80080816b4f52a9d886e67f1f96912891074903238fe54f2de8b786f86baded2"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:84433dddea68571a6d6bd4fbf8ff398236031149116a7fff6f777ff95cad3df9"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19a2d91963ed9e42b4e8d77cd847ae8381576585bad79dbd0a8837a9f6620a"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:59556bf80a7094d0cfb9f5e50bb2db27fefb75d5138bb16fb052b61b0e0eeeb0"}, + {file = "zstandard-0.23.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:27d3ef2252d2e62476389ca8f9b0cf2bbafb082a3b6bfe9d90cbcbb5529ecf7c"}, + {file = "zstandard-0.23.0-cp310-cp310-win32.whl", hash = "sha256:5d41d5e025f1e0bccae4928981e71b2334c60f580bdc8345f824e7c0a4c2a813"}, + {file = "zstandard-0.23.0-cp310-cp310-win_amd64.whl", hash = "sha256:519fbf169dfac1222a76ba8861ef4ac7f0530c35dd79ba5727014613f91613d4"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34895a41273ad33347b2fc70e1bff4240556de3c46c6ea430a7ed91f9042aa4e"}, + {file = "zstandard-0.23.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:77ea385f7dd5b5676d7fd943292ffa18fbf5c72ba98f7d09fc1fb9e819b34c23"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:983b6efd649723474f29ed42e1467f90a35a74793437d0bc64a5bf482bedfa0a"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80a539906390591dd39ebb8d773771dc4db82ace6372c4d41e2d293f8e32b8db"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:445e4cb5048b04e90ce96a79b4b63140e3f4ab5f662321975679b5f6360b90e2"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd30d9c67d13d891f2360b2a120186729c111238ac63b43dbd37a5a40670b8ca"}, + {file = "zstandard-0.23.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d20fd853fbb5807c8e84c136c278827b6167ded66c72ec6f9a14b863d809211c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ed1708dbf4d2e3a1c5c69110ba2b4eb6678262028afd6c6fbcc5a8dac9cda68e"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:be9b5b8659dff1f913039c2feee1aca499cfbc19e98fa12bc85e037c17ec6ca5"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65308f4b4890aa12d9b6ad9f2844b7ee42c7f7a4fd3390425b242ffc57498f48"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98da17ce9cbf3bfe4617e836d561e433f871129e3a7ac16d6ef4c680f13a839c"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:8ed7d27cb56b3e058d3cf684d7200703bcae623e1dcc06ed1e18ecda39fee003"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:b69bb4f51daf461b15e7b3db033160937d3ff88303a7bc808c67bbc1eaf98c78"}, + {file = "zstandard-0.23.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:034b88913ecc1b097f528e42b539453fa82c3557e414b3de9d5632c80439a473"}, + {file = "zstandard-0.23.0-cp311-cp311-win32.whl", hash = "sha256:f2d4380bf5f62daabd7b751ea2339c1a21d1c9463f1feb7fc2bdcea2c29c3160"}, + {file = "zstandard-0.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:62136da96a973bd2557f06ddd4e8e807f9e13cbb0bfb9cc06cfe6d98ea90dfe0"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b4567955a6bc1b20e9c31612e615af6b53733491aeaa19a6b3b37f3b65477094"}, + {file = "zstandard-0.23.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e172f57cd78c20f13a3415cc8dfe24bf388614324d25539146594c16d78fcc8"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0e166f698c5a3e914947388c162be2583e0c638a4703fc6a543e23a88dea3c1"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12a289832e520c6bd4dcaad68e944b86da3bad0d339ef7989fb7e88f92e96072"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d50d31bfedd53a928fed6707b15a8dbeef011bb6366297cc435accc888b27c20"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72c68dda124a1a138340fb62fa21b9bf4848437d9ca60bd35db36f2d3345f373"}, + {file = "zstandard-0.23.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53dd9d5e3d29f95acd5de6802e909ada8d8d8cfa37a3ac64836f3bc4bc5512db"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6a41c120c3dbc0d81a8e8adc73312d668cd34acd7725f036992b1b72d22c1772"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40b33d93c6eddf02d2c19f5773196068d875c41ca25730e8288e9b672897c105"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9206649ec587e6b02bd124fb7799b86cddec350f6f6c14bc82a2b70183e708ba"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76e79bc28a65f467e0409098fa2c4376931fd3207fbeb6b956c7c476d53746dd"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:66b689c107857eceabf2cf3d3fc699c3c0fe8ccd18df2219d978c0283e4c508a"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9c236e635582742fee16603042553d276cca506e824fa2e6489db04039521e90"}, + {file = "zstandard-0.23.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a8fffdbd9d1408006baaf02f1068d7dd1f016c6bcb7538682622c556e7b68e35"}, + {file = "zstandard-0.23.0-cp312-cp312-win32.whl", hash = "sha256:dc1d33abb8a0d754ea4763bad944fd965d3d95b5baef6b121c0c9013eaf1907d"}, + {file = "zstandard-0.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:64585e1dba664dc67c7cdabd56c1e5685233fbb1fc1966cfba2a340ec0dfff7b"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9"}, + {file = "zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed"}, + {file = "zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057"}, + {file = "zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33"}, + {file = "zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd"}, + {file = "zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2ef3775758346d9ac6214123887d25c7061c92afe1f2b354f9388e9e4d48acfc"}, + {file = "zstandard-0.23.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4051e406288b8cdbb993798b9a45c59a4896b6ecee2f875424ec10276a895740"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d1a054f8f0a191004675755448d12be47fa9bebbcffa3cdf01db19f2d30a54"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f83fa6cae3fff8e98691248c9320356971b59678a17f20656a9e59cd32cee6d8"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:32ba3b5ccde2d581b1e6aa952c836a6291e8435d788f656fe5976445865ae045"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f146f50723defec2975fb7e388ae3a024eb7151542d1599527ec2aa9cacb152"}, + {file = "zstandard-0.23.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1bfe8de1da6d104f15a60d4a8a768288f66aa953bbe00d027398b93fb9680b26"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:29a2bc7c1b09b0af938b7a8343174b987ae021705acabcbae560166567f5a8db"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:61f89436cbfede4bc4e91b4397eaa3e2108ebe96d05e93d6ccc95ab5714be512"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53ea7cdc96c6eb56e76bb06894bcfb5dfa93b7adcf59d61c6b92674e24e2dd5e"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a4ae99c57668ca1e78597d8b06d5af837f377f340f4cce993b551b2d7731778d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:379b378ae694ba78cef921581ebd420c938936a153ded602c4fea612b7eaa90d"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:50a80baba0285386f97ea36239855f6020ce452456605f262b2d33ac35c7770b"}, + {file = "zstandard-0.23.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:61062387ad820c654b6a6b5f0b94484fa19515e0c5116faf29f41a6bc91ded6e"}, + {file = "zstandard-0.23.0-cp38-cp38-win32.whl", hash = "sha256:b8c0bd73aeac689beacd4e7667d48c299f61b959475cdbb91e7d3d88d27c56b9"}, + {file = "zstandard-0.23.0-cp38-cp38-win_amd64.whl", hash = "sha256:a05e6d6218461eb1b4771d973728f0133b2a4613a6779995df557f70794fd60f"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa014d55c3af933c1315eb4bb06dd0459661cc0b15cd61077afa6489bec63bb"}, + {file = "zstandard-0.23.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7f0804bb3799414af278e9ad51be25edf67f78f916e08afdb983e74161b916"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb2b1ecfef1e67897d336de3a0e3f52478182d6a47eda86cbd42504c5cbd009a"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:837bb6764be6919963ef41235fd56a6486b132ea64afe5fafb4cb279ac44f259"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1516c8c37d3a053b01c1c15b182f3b5f5eef19ced9b930b684a73bad121addf4"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48ef6a43b1846f6025dde6ed9fee0c24e1149c1c25f7fb0a0585572b2f3adc58"}, + {file = "zstandard-0.23.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11e3bf3c924853a2d5835b24f03eeba7fc9b07d8ca499e247e06ff5676461a15"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2fb4535137de7e244c230e24f9d1ec194f61721c86ebea04e1581d9d06ea1269"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8c24f21fa2af4bb9f2c492a86fe0c34e6d2c63812a839590edaf177b7398f700"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8c86881813a78a6f4508ef9daf9d4995b8ac2d147dcb1a450448941398091c9"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe3b385d996ee0822fd46528d9f0443b880d4d05528fd26a9119a54ec3f91c69"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:82d17e94d735c99621bf8ebf9995f870a6b3e6d14543b99e201ae046dfe7de70"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c7c517d74bea1a6afd39aa612fa025e6b8011982a0897768a2f7c8ab4ebb78a2"}, + {file = "zstandard-0.23.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fd7e0f1cfb70eb2f95a19b472ee7ad6d9a0a992ec0ae53286870c104ca939e5"}, + {file = "zstandard-0.23.0-cp39-cp39-win32.whl", hash = "sha256:43da0f0092281bf501f9c5f6f3b4c975a8a0ea82de49ba3f7100e64d422a1274"}, + {file = "zstandard-0.23.0-cp39-cp39-win_amd64.whl", hash = "sha256:f8346bfa098532bc1fb6c7ef06783e969d87a99dd1d2a5a18a892c1d7a643c58"}, + {file = "zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09"}, +] + +[package.dependencies] +cffi = {version = ">=1.11", markers = "platform_python_implementation == \"PyPy\""} + +[package.extras] +cffi = ["cffi (>=1.11)"] + +[metadata] +lock-version = "2.1" +python-versions = ">=3.10,<3.13" +content-hash = "78aab6d18a12428089562fdf3d3d8e804ea4e5fb4778af46e22530740b5afb1c" diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml b/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml new file mode 100644 index 00000000..da5556b3 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml @@ -0,0 +1,26 @@ +[tool.poetry] +name = "langgraph_agentic_rag" +version = "0.1.0" +description = "A template for an Agentic RAG LangGraph app deployable on IBM Cloud as an ai_service. This particular example focuses on a WatsonX chatbot enhanced with watsonx Utility Agent Tool 'RAGQuery'." +authors = ["Your Name "] +license = "MIT" +readme = "README.md" +packages = [ + { include = "langgraph_agentic_rag", from = "src" } +] + + +[tool.poetry.dependencies] +python = ">=3.10,<3.13" +langchain-ibm = "^0.3.9" +python-dotenv = "^1.0.1" +ibm-watsonx-ai = { version = ">=1.1.22", python = ">=3.11,<3.13" } +langgraph = ">0.2,<0.3" +langchain = "^0.3.21" +pytest = "^8.3.3" +langchain-community = "0.3.16" +psycopg2-binary = "2.9.10" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/request.json b/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/request.json new file mode 100644 index 00000000..03b90bb4 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/request.json @@ -0,0 +1,37 @@ +{ + "application/json": { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "messages": { + "title": "The messages for this chat session.", + "type": "array", + "items": { + "type": "object", + "properties": { + "role": { + "title": "The role of the message author.", + "type": "string", + "enum": [ + "user", + "assistant", + "system" + ] + }, + "content": { + "title": "The contents of the message.", + "type": "string" + } + }, + "required": [ + "role", + "content" + ] + } + } + }, + "required": [ + "messages" + ] + } +} \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/response.json b/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/response.json new file mode 100644 index 00000000..9fb5d30e --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/schema/response.json @@ -0,0 +1,86 @@ +{ + "application/json": { + "oneOf": [ + { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "AI Service response for /ai_service_stream", + "properties": { + "choices": { + "description": "A list of chat completion choices.", + "type": "array", + "items": { + "type": "object", + "properties": { + "index": { + "type": "integer", + "title": "The index of this result." + }, + "delta": { + "description": "A message result.", + "type": "object", + "properties": { + "content": { + "description": "The contents of the message.", + "type": "string" + }, + "role": { + "description": "The role of the author of this message.", + "type": "string" + } + }, + "required": [ + "role" + ] + } + } + } + } + }, + "required": [ + "choices" + ] + }, + { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "AI Service response for /ai_service", + "properties": { + "choices": { + "description": "A list of chat completion choices", + "type": "array", + "items": { + "type": "object", + "properties": { + "index": { + "type": "integer", + "description": "The index of this result." + }, + "message": { + "description": "A message result.", + "type": "object", + "properties": { + "role": { + "description": "The role of the author of this message.", + "type": "string" + }, + "content": { + "title": "Message content.", + "type": "string" + } + }, + "required": [ + "role" + ] + } + } + } + } + }, + "required": [ + "choices" + ] + } + ] + } +} \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/build_package.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/build_package.py new file mode 100644 index 00000000..fe8625bd --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/build_package.py @@ -0,0 +1,58 @@ +import shutil +import subprocess +import tomllib +from pathlib import Path + + +def get_package_name_and_version(pyproject_path: str) -> tuple[str, str]: + """ + Parse pyproject.toml to get the package name and version. + + :param pyproject_path: Path to pyproject.toml + :type pyproject_path: str + """ + with open(pyproject_path, "rb") as f: + pyproject_data = tomllib.load(f) + tool_poetry = pyproject_data.get("tool", {}).get("poetry", {}) + package_name = tool_poetry.get("name") + package_version = tool_poetry.get("version") + if not package_name or not package_version: + raise ValueError("Package name or version is missing in pyproject.toml.") + return package_name, package_version + + +def build_zip_sc(sc_dir: Path) -> None: + """ + Build and package a source distribution as a ZIP archive. + + This function performs the following steps: + 1. Builds a source distribution using Poetry. + 2. Extracts the built archive. + 3. Normalizes file timestamps to fix ZIP timestamp issues. + 4. Creates a ZIP archive of the source directory. + + :param sc_dir: Path to the source directory for building and packaging. + :type sc_dir: Path + """ + subprocess.run( + ["poetry", "build", f"--output={sc_dir.parent}", "--format=sdist"], check=True + ) + shutil.unpack_archive(sc_dir.with_suffix(".tar.gz"), sc_dir.parent) + + for file in sc_dir.parent.rglob("*"): + if file.is_file(): + file.touch() + + zip_dir = str(sc_dir.with_suffix("")) + shutil.make_archive(zip_dir, "zip", zip_dir) + + +if __name__ == "__main__": + pkg_name, pkg_version = get_package_name_and_version("../pyproject.toml") + pkg_ext_sc = ( + Path(__file__).parent + / ".." + / "dist" + / f"{pkg_name.replace('-', '_')}-{pkg_version}.zip" + ) + build_zip_sc(pkg_ext_sc) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/deploy.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/deploy.py new file mode 100644 index 00000000..fb343c88 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/scripts/deploy.py @@ -0,0 +1,112 @@ +import json +import logging +from pathlib import Path +import json + +import ibm_watsonx_ai + +from ai_service import deployable_ai_service +from scripts.build_package import build_zip_sc, get_package_name_and_version +from utils import load_config + +logging.basicConfig() +logger = logging.getLogger(__name__) + +config = load_config() +dep_config = config["deployment"] + +client = ibm_watsonx_ai.APIClient( + credentials=ibm_watsonx_ai.Credentials( + url=dep_config["watsonx_url"], api_key=dep_config["watsonx_apikey"] + ), + space_id=dep_config["space_id"], +) + +root_dir = Path(__file__).parents[1] +pyproject_path = root_dir / "pyproject.toml" +pkg_name, pkg_version = get_package_name_and_version(str(pyproject_path)) + +# Create package extension +pkg_ext_metadata = { + client.package_extensions.ConfigurationMetaNames.NAME: pkg_name, + client.package_extensions.ConfigurationMetaNames.TYPE: "pip_zip", +} + +pkg_ext_sc = root_dir / "dist" / f"{pkg_name.replace('-', '_')}-{pkg_version}.zip" + +if not pkg_ext_sc.exists(): + build_zip_sc(pkg_ext_sc) +else: + logger.warning( + f"package extension was not built as path: '{pkg_ext_sc}' is not empty. Using the already existing path for deployment. " + "In case of any problems you might want to delete it and rerun the `deploy.py` script" + ) + +pkg_ext_asset_details = client.package_extensions.store( + meta_props=pkg_ext_metadata, file_path=str(pkg_ext_sc) +) +pkg_ext_asset_id = client.package_extensions.get_id(pkg_ext_asset_details) + +# Select base software specification to extend +base_sw_spec_id = client.software_specifications.get_id_by_name("runtime-24.1-py3.11") + +# Define new software specification based on base one and custom library +template_sw_spec_name = f"{pkg_name}-sw-spec" + +sw_spec_metadata = { + client.software_specifications.ConfigurationMetaNames.NAME: template_sw_spec_name, + client.software_specifications.ConfigurationMetaNames.BASE_SOFTWARE_SPECIFICATION: { + "guid": base_sw_spec_id + }, + client.software_specifications.ConfigurationMetaNames.PACKAGE_EXTENSIONS: [ + {"guid": pkg_ext_asset_id} + ], +} + +# Delete if sw_spec already exists +try: + sw_spec_id = client.software_specifications.get_id_by_name(template_sw_spec_name) + logger.warning(f"Deleting previously created sw_spec: {template_sw_spec_name}") + client.software_specifications.delete(sw_spec_id) +except ibm_watsonx_ai.wml_client_error.ResourceIdByNameNotFound: + pass + +# Store the software spec +sw_spec_asset_details = client.software_specifications.store( + meta_props=sw_spec_metadata +) + +# Get the id of the new asset +asset_id = client.software_specifications.get_id(sw_spec_asset_details) + +sw_spec_asset_details = client.software_specifications.get_details(asset_id) + + +with (root_dir / "schema" / "request.json").open("r", encoding="utf-8") as file: + request_schema = json.load(file) + +with (root_dir / "schema" / "response.json").open("r", encoding="utf-8") as file: + response_schema = json.load(file) + +meta_props = { + client.repository.AIServiceMetaNames.SOFTWARE_SPEC_ID: asset_id, + client.repository.AIServiceMetaNames.NAME: "online ai_service", + client.repository.AIServiceMetaNames.REQUEST_DOCUMENTATION: request_schema, + client.repository.AIServiceMetaNames.RESPONSE_DOCUMENTATION: response_schema, + client.repository.AIServiceMetaNames.TAGS: ["wx-agent"], +} + +stored_ai_service_details = client.repository.store_ai_service( + deployable_ai_service, meta_props +) +ai_service_id = stored_ai_service_details["metadata"].get("id") + +meta_props = { + client.deployments.ConfigurationMetaNames.NAME: f"online ai_service test", + client.deployments.ConfigurationMetaNames.ONLINE: { + "parameters": dep_config["online"]["parameters"] + }, + client.repository.AIServiceMetaNames.TAGS: ["wx-agent"], +} + +deployment_details = client.deployments.create(ai_service_id, meta_props) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py new file mode 100644 index 00000000..1358ef9a --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py @@ -0,0 +1 @@ +from .tools import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py new file mode 100644 index 00000000..f5cab8a9 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py @@ -0,0 +1,301 @@ +from typing import Callable, Annotated, Sequence + +from typing_extensions import TypedDict +from langchain_core.prompts import PromptTemplate, ChatPromptTemplate + +from ibm_watsonx_ai import APIClient +from langchain_ibm import ChatWatsonx +from pydantic import BaseModel, Field +from typing import Literal + +from langgraph.graph import END, StateGraph, START +from langgraph.graph.graph import CompiledGraph +from langgraph.graph.message import add_messages + +from langgraph.prebuilt import ToolNode, tools_condition +from langgraph.checkpoint.memory import MemorySaver + +from langchain import hub +from langchain_core.output_parsers import StrOutputParser +from langchain_core.messages import BaseMessage, SystemMessage, AIMessage, HumanMessage + +from langgraph_agentic_rag import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx + + +def get_graph_closure( + client: APIClient, + model_id: str, + tool_config: dict, + base_knowledge_description: str | None = None, +) -> Callable: + """Graph generator closure.""" + + # Initialise ChatWatsonx + chat = ChatWatsonx(model_id=model_id, watsonx_client=client) + chat_grader = ChatWatsonx(model_id=model_id, watsonx_client=client, disable_streaming = True) + + TOOLS = [ + retriever_tool_watsonx( + api_client=client, + tool_config=tool_config, + ), + sql_retriever_tool_watsonx( + api_client=client, + ), + websearch_tool_watsonx( + api_client=client, + tool_config={"maxResults": 3}, + ), + + ] + + # Initialise memory saver + # memory = MemorySaver() + + # Define system prompt + default_system_prompt = ( + f"You are a helpful AI assistant, please respond to the user's query to the best of your ability!" + "\n\n" + f"Vector Store Index knowledge description: {base_knowledge_description or ''}" + ) + + class AgentState(TypedDict): + # The add_messages function defines how an update should be processed + # Default is to replace. add_messages says "append" + messages: Annotated[Sequence[BaseMessage], add_messages] + + ### Nodes + + def agent_with_instruction(instruction_prompt: str | None) -> Callable: + """System prompt will be updated by instruction prompt.""" + + def agent(state: AgentState) -> dict: + """ + Invokes the agent model to generate a response based on the current state. Given + the question, it will decide to retrieve using the retriever tool, or simply end. + + Args: + state (messages): The current state + + Returns: + dict: The updated state with the agent response appended to messages + """ + messages = state["messages"] + tools_used = [] + # query = messages[0] + for m in reversed(messages): + if hasattr(m, 'tool_call_id'): + print((f"I have tried tool: {m.name}")) + tools_used.append(m.name) + if m.type == "human": + # query = m.content + query = m + break + + unused_tools = [t for t in TOOLS if t.name not in tools_used] + if len(unused_tools) < 1: + unused_tools = [websearch_tool_watsonx(api_client=client, tool_config={"maxResults": 3})] + + model = chat.bind_tools(unused_tools) + print(f"unused tools: {[u.name for u in unused_tools]}") + + system_prompt = SystemMessage( + default_system_prompt + "\n" + (instruction_prompt or "") + ) + # response = model.invoke([system_prompt] + list(messages)) + response = model.invoke([query]) + # We return a list, because this will get added to the existing list + return {"messages": [response]} + + return agent + + def generate(state: AgentState): + """ + Generate answer + + Args: + state (messages): The current state + + Returns: + dict: The updated state with re-phrased question + """ + messages = state["messages"] + + # Most recent user query + # question = messages[-3].content + for m in reversed(messages): + if m.type == "human": + question = m.content + + # Tool content + last_message = messages[-1] + docs = last_message.content + + # Prompt + prompt = ChatPromptTemplate([ + ("user", "You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If there is no context, just answer the question to be best of your knowledge. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.\nQuestion: {question} \nContext: {context} \nAnswer:") + ]) + + # Chain + rag_chain = prompt | chat + + # Run + response = rag_chain.invoke({"context": docs, "question": question}) + return {"messages": [response]} + + + # Edges + def grade_documents(state) -> Literal["generate", "agent"]: + """ + Determines whether the retrieved documents are relevant to the question. + + Args: + state (messages): The current state + + Returns: + str: A decision for whether the documents are relevant or not + """ + + # logger.info("---CHECK RELEVANCE---") + print("---CHECK RELEVANCE---") + + # Data model + class grade(BaseModel): + """Binary score for relevance check.""" + binary_score: str = Field(description="Relevance score 'yes' or 'no'") + + + # LLM with tool and validation + llm_with_tool = chat_grader.with_structured_output(grade) + + # Prompt + prompt = PromptTemplate( + template="""You are a grader assessing relevance of a retrieved document to a user question. \n + Here is the retrieved document: \n\n {context} \n\n + Here is the user question: {question} \n + If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \n + If the document mentions it has no data or no results to answer the question, or if the data is not directly available to answer the user question, it means the document is not relevant and grade it as 'no'. \n + Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.""", + input_variables=["context", "question"], + ) + + # Chain + chain = prompt | llm_with_tool + + messages = state["messages"] + last_message = messages[-1] + + # question = messages[0].content + msg_cnt = 0 + for m in reversed(messages): + if m.type == "human": + question = m.content + msg_cnt += 1 + break + + docs = last_message.content + + scored_result = chain.invoke({"question": question, "context": docs}) + + score = scored_result.binary_score + # for m in messages: + # print(m.type, "[messages]", m) + if msg_cnt > 12: + score = "yes" + print("number of messages",len(messages)) + + if score == "yes": + print("---DECISION: DOCS RELEVANT---") + return "generate" + + else: + print("---DECISION: DOCS NOT RELEVANT---") + return "agent" + + + def rewrite(state): + """ + Transform the query to produce a better question. + + Args: + state (messages): The current state + + Returns: + dict: The updated state with re-phrased question + """ + + # logger.info("---TRANSFORM QUERY---") + print("---TRANSFORM QUERY---") + messages = state["messages"] + # question = messages[0].content + for m in reversed(messages): + if m.type == "human": + question = m.content + break + + + msg = [ + HumanMessage( + content=f""" \n + Look at the input and try to reason about the underlying semantic intent / meaning. \n + Here is the initial question: + \n ------- \n + {question} + \n ------- \n + Formulate an improved question, output the question only: """, + ) + ] + response = chat.invoke(msg) + print("rewrite message", response) + return {"messages": [response]} + + def get_graph(instruction_prompt: SystemMessage | None = None) -> CompiledGraph: + """Get compiled graph with overwritten system prompt, if provided""" + + # Define a new graph + workflow = StateGraph(AgentState) + + if instruction_prompt is None: + agent = agent_with_instruction(instruction_prompt) + else: + agent = agent_with_instruction(instruction_prompt.content) + + # Define the nodes + workflow.add_node("agent", agent) # agent + retrieve = ToolNode(TOOLS) + # workflow.add_node("rewrite", rewrite) + workflow.add_node("retrieve", retrieve) # retrieval + workflow.add_node("generate", generate) # generate answer + + # Call agent node to decide to retrieve or not + workflow.add_edge(START, "agent") + + # Decide whether to retrieve + workflow.add_conditional_edges( + "agent", + # Assess agent decision + tools_condition, + { + # Translate the condition outputs to nodes in our graph + "tools": "retrieve", + END: "generate", + }, + ) + workflow.add_conditional_edges( + "retrieve", + # Assess agent decision + grade_documents, + ) + + # Edges taken after the `action` node is called. + # workflow.add_edge("retrieve", "generate") + workflow.add_edge("generate", END) + # workflow.add_edge("rewrite", "agent") + + # Compile + # graph = workflow.compile(checkpointer=memory) + graph = workflow.compile() + + return graph + + return get_graph diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py new file mode 100644 index 00000000..9c0077c1 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py @@ -0,0 +1,140 @@ +from typing import Callable, TYPE_CHECKING +from typing import Any, List + +from langchain_core.tools import tool +# from langchain_core.retrievers import BaseRetriever +# from langchain.tools.retriever import create_retriever_tool +from langchain.chains import create_sql_query_chain +from langchain_community.utilities import SQLDatabase +from langchain_ibm import ChatWatsonx + + +if TYPE_CHECKING: + from ibm_watsonx_ai import APIClient + + +# class NL2SQLRetriever(BaseRetriever): + +# def _get_relevant_documents( +# self, query: str, *, run_manager: CallbackManagerForRetrieverRun +# ) -> List[Document]: +# """ +# Retrieve relevant documents based on a natural language query from a postgres database. + +# Args: +# query (str): The query to search for relevant documents. + +# Returns: +# List[Document]: A list of relevant documents retrieved based on the query. +# """ + +# llm = ChatWatsonx( +# model_id="meta-llama/llama-3-3-70b-instruct", +# url="https://us-south.ml.cloud.ibm.com", +# project_id=os.getenv("PROJECT_ID"), +# params={ +# "decoding_method": "greedy", +# "max_new_tokens": 1000, +# "min_new_tokens": 1, +# }, +# ) + + +# db_uri = os.getenv("PG_URI") +# db = SQLDatabase.from_uri(db_uri) +# chain = create_sql_query_chain(llm, db) +# response = chain.invoke({"question": query}) + +# return [Document(page_content=response)] + +# def create_sql_retriever_tool(name = "sql_retrieve_documents", description = "Search and return information from SQL database"): +# retriever = NL2SQLRetriever() +# retriever_tool = create_retriever_tool( +# retriever, +# name, +# description, +# ) +# return retriever_tool + +def sql_retriever_tool_watsonx( + api_client: "APIClient", +) -> Callable: + + db_uri = "" + db = SQLDatabase.from_uri(db_uri) + model_id = "meta-llama/llama-3-3-70b-instruct" + llm = ChatWatsonx(model_id=model_id, watsonx_client=api_client, disable_streaming = True) + chain = create_sql_query_chain(llm, db) + + @tool("sql_retriever", parse_docstring=True) + def sql_retriever_tool(query: str) -> str: + """ + SQL retrieval tool for sustainability statistics for suppliers such as scope 1 and scope 2 carbon emmisions and revenue. + + Args: + query: User query related to information stored in Vector Index. + + Returns: + Retrieved chunk. + """ + + return chain.invoke({"question": query}) + + return sql_retriever_tool + + + +def retriever_tool_watsonx( + api_client: "APIClient", + tool_config: dict, +) -> Callable: + + from langchain_ibm.toolkit import WatsonxToolkit + + toolkit = WatsonxToolkit(watsonx_client=api_client) + + rag_tool = toolkit.get_tool("RAGQuery") + rag_tool.set_tool_config(tool_config) + + @tool("vectordb_retriever", parse_docstring=True) + def retriever_tool(query: str) -> str: + """ + Vector Store Index retriever tool to retrieve sustainability reports. + + Args: + query: User query related to information stored in Vector Index. + + Returns: + Retrieved chunk. + """ + return rag_tool.invoke({"input": query})["output"] + + return retriever_tool + + +def websearch_tool_watsonx( + api_client: "APIClient", + tool_config: dict, +) -> Callable: + + from langchain_ibm.toolkit import WatsonxToolkit + + toolkit = WatsonxToolkit(watsonx_client=api_client) + + rag_tool = toolkit.get_tool("GoogleSearch") + rag_tool.set_tool_config(tool_config) + + @tool("websearch", parse_docstring=True) + def websearch_tool(query: str) -> str: + """ + Search for online trends, news, current events, real-time information, or research topics. + + Args: + query: User query related to information on the internet. + + Returns: + Retrieved chunk. + """ + return rag_tool.invoke({"input": query})["output"] + + return websearch_tool \ No newline at end of file diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/tests/__init__.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/tests/test_tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/tests/test_tools.py new file mode 100644 index 00000000..505bc2b3 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/tests/test_tools.py @@ -0,0 +1,27 @@ +from ibm_watsonx_ai import Credentials, APIClient + +from utils import load_config +from langgraph_agentic_rag import retriever_tool_watsonx + +config = load_config() + +dep_config = config["deployment"] + +api_client = APIClient( + credentials=Credentials( + url=dep_config["watsonx_url"], api_key=dep_config["watsonx_apikey"] + ) +) + +tool_config = { + "projectId": dep_config["custom"]["tool_config_projectId"], + "vectorIndexId": dep_config["custom"]["tool_config_vectorIndexId"], +} + + +class TestTools: + def test_dummy_vector_index_run(self): + query = "IBM" + rag_tool = retriever_tool_watsonx(api_client, tool_config) + result = rag_tool.invoke({"query": query}) + assert "output" in result # Check if the tool returns correct payload diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/utils.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/utils.py new file mode 100644 index 00000000..e211a5d2 --- /dev/null +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/utils.py @@ -0,0 +1,10 @@ +import tomllib +from pathlib import Path + + +def load_config(section: str | None = None) -> dict: + config = tomllib.loads((Path(__file__).parent / "config.toml").read_text()) + if section is not None: + return config[section] + else: + return config From 89eb092897a191d36de6e3bb5c3488d66ef4ee0b Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 9 Apr 2025 01:09:59 +1200 Subject: [PATCH 2/8] added secrets Signed-off-by: Shuang Yu --- .../examples/query_existing_deployment.py | 4 +- .../poetry.lock | 60 +++++++++++++++++- .../pyproject.toml | 1 + .../src/langgraph_agentic_rag/agent.py | 40 +----------- .../src/langgraph_agentic_rag/tools.py | 63 +++++++------------ 5 files changed, 86 insertions(+), 82 deletions(-) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py index c2ba3925..3548ac51 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/examples/query_existing_deployment.py @@ -3,7 +3,7 @@ from utils import load_config from examples._interactive_chat import InteractiveChat -deployment_id = "b7d2a4d0-0a97-42c2-80ea-8c39623a14d8" +deployment_id = "8af73a87-a451-4d64-8dd7-f5fea7abd8c0" stream = True config = load_config("deployment") @@ -14,7 +14,7 @@ space_id=config["space_id"], ) -# # Executing deployed AI service with provided scoring data +# Executing deployed AI service with provided scoring data # if stream: # ai_service_invoke = lambda payload: client.deployments.run_ai_service_stream( # deployment_id, payload diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock b/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock index 84eb7ac1..dada6e4c 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/poetry.lock @@ -700,6 +700,28 @@ files = [ {file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"}, ] +[[package]] +name = "ibm-cloud-sdk-core" +version = "3.23.0" +description = "Core library used by SDKs for IBM Cloud Services" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "ibm_cloud_sdk_core-3.23.0-py3-none-any.whl", hash = "sha256:9cbdd27de2306abd0916f6905b1d8aaa73b1bae510a4dc2a49fa2a62d40a6de5"}, + {file = "ibm_cloud_sdk_core-3.23.0.tar.gz", hash = "sha256:393cb7c8e747d2706f495bc29ae54871979ab2f2e7cb907cd4d4d4f011a92d93"}, +] + +[package.dependencies] +PyJWT = ">=2.8.0,<3.0.0" +python_dateutil = ">=2.8.2,<3.0.0" +requests = ">=2.31.0,<3.0.0" +urllib3 = ">=2.1.0,<3.0.0" + +[package.extras] +dev = ["black (>=24.0.0,<25.0.0)", "coverage (>=7.3.2,<8.0.0)", "pylint (>=3.0.0,<4.0.0)", "pytest (>=7.4.2,<8.0.0)", "pytest-cov (>=4.1.0,<5.0.0)", "responses (>=0.23.3,<1.0.0)"] +publish = ["build", "twine"] + [[package]] name = "ibm-cos-sdk" version = "2.13.5" @@ -747,6 +769,24 @@ files = [ [package.dependencies] ibm-cos-sdk-core = "2.13.5" +[[package]] +name = "ibm-secrets-manager-sdk" +version = "2.1.9" +description = "IBM Cloud Secrets Manager Python SDK" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "ibm_secrets_manager_sdk-2.1.9-py3-none-any.whl", hash = "sha256:d066beb65ecf522280fb40addfca90d151b998cd6a5af03dd6612a7c976a703c"}, + {file = "ibm_secrets_manager_sdk-2.1.9.tar.gz", hash = "sha256:9ce6f02b6a290f984ba8a410ccee2800611cc9922c97e5996eea3d1137668788"}, +] + +[package.dependencies] +ibm_cloud_sdk_core = ">=3.21.0,<4.0.0" +python_dateutil = ">=2.5.3,<3.0.0" +requests = ">=2.28.2,<3.0.0" +urllib3 = ">=2.1.0,<3.0.0" + [[package]] name = "ibm-watsonx-ai" version = "1.3.3" @@ -1908,6 +1948,24 @@ azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0 toml = ["tomli (>=2.0.1)"] yaml = ["pyyaml (>=6.0.1)"] +[[package]] +name = "pyjwt" +version = "2.10.1" +description = "JSON Web Token implementation in Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, +] + +[package.extras] +crypto = ["cryptography (>=3.4.0)"] +dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] +tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] + [[package]] name = "pytest" version = "8.3.5" @@ -2552,4 +2610,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.13" -content-hash = "78aab6d18a12428089562fdf3d3d8e804ea4e5fb4778af46e22530740b5afb1c" +content-hash = "a9328cecd6956b7e96d0e95d139ceae8b0c59e219885c25e18ec8436afedc8ac" diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml b/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml index da5556b3..5e51af43 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/pyproject.toml @@ -20,6 +20,7 @@ langchain = "^0.3.21" pytest = "^8.3.3" langchain-community = "0.3.16" psycopg2-binary = "2.9.10" +ibm-secrets-manager-sdk = "^2.1.9" [build-system] requires = ["poetry-core"] diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py index f5cab8a9..22292c87 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py @@ -32,7 +32,8 @@ def get_graph_closure( # Initialise ChatWatsonx chat = ChatWatsonx(model_id=model_id, watsonx_client=client) - chat_grader = ChatWatsonx(model_id=model_id, watsonx_client=client, disable_streaming = True) + grader_model_id = "meta-llama/llama-4-maverick-17b-128e-instruct-fp8" + chat_grader = ChatWatsonx(model_id=grader_model_id, watsonx_client=client, disable_streaming = True) TOOLS = [ retriever_tool_watsonx( @@ -88,7 +89,6 @@ def agent(state: AgentState) -> dict: print((f"I have tried tool: {m.name}")) tools_used.append(m.name) if m.type == "human": - # query = m.content query = m break @@ -211,43 +211,7 @@ class grade(BaseModel): else: print("---DECISION: DOCS NOT RELEVANT---") return "agent" - - - def rewrite(state): - """ - Transform the query to produce a better question. - - Args: - state (messages): The current state - - Returns: - dict: The updated state with re-phrased question - """ - # logger.info("---TRANSFORM QUERY---") - print("---TRANSFORM QUERY---") - messages = state["messages"] - # question = messages[0].content - for m in reversed(messages): - if m.type == "human": - question = m.content - break - - - msg = [ - HumanMessage( - content=f""" \n - Look at the input and try to reason about the underlying semantic intent / meaning. \n - Here is the initial question: - \n ------- \n - {question} - \n ------- \n - Formulate an improved question, output the question only: """, - ) - ] - response = chat.invoke(msg) - print("rewrite message", response) - return {"messages": [response]} def get_graph(instruction_prompt: SystemMessage | None = None) -> CompiledGraph: """Get compiled graph with overwritten system prompt, if provided""" diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py index 9c0077c1..3a5e0f4e 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py @@ -1,9 +1,10 @@ from typing import Callable, TYPE_CHECKING from typing import Any, List +from ibm_cloud_sdk_core.authenticators.bearer_token_authenticator import BearerTokenAuthenticator +from ibm_secrets_manager_sdk.secrets_manager_v2 import SecretsManagerV2 + from langchain_core.tools import tool -# from langchain_core.retrievers import BaseRetriever -# from langchain.tools.retriever import create_retriever_tool from langchain.chains import create_sql_query_chain from langchain_community.utilities import SQLDatabase from langchain_ibm import ChatWatsonx @@ -13,54 +14,32 @@ from ibm_watsonx_ai import APIClient -# class NL2SQLRetriever(BaseRetriever): - -# def _get_relevant_documents( -# self, query: str, *, run_manager: CallbackManagerForRetrieverRun -# ) -> List[Document]: -# """ -# Retrieve relevant documents based on a natural language query from a postgres database. - -# Args: -# query (str): The query to search for relevant documents. - -# Returns: -# List[Document]: A list of relevant documents retrieved based on the query. -# """ - -# llm = ChatWatsonx( -# model_id="meta-llama/llama-3-3-70b-instruct", -# url="https://us-south.ml.cloud.ibm.com", -# project_id=os.getenv("PROJECT_ID"), -# params={ -# "decoding_method": "greedy", -# "max_new_tokens": 1000, -# "min_new_tokens": 1, -# }, -# ) +def get_secret(api_client, secret_name): + service_url = "https://a14f50a6-1721-4bd9-930c-403264d61ec1.au-syd.secrets-manager.appdomain.cloud" + secretsManager = SecretsManagerV2( + authenticator=BearerTokenAuthenticator(bearer_token=api_client.token), + ) + secretsManager.set_service_url(service_url.format(instance_ID="insatnce_id")) -# db_uri = os.getenv("PG_URI") -# db = SQLDatabase.from_uri(db_uri) -# chain = create_sql_query_chain(llm, db) -# response = chain.invoke({"question": query}) + # response = secretsManager.get_secret('1a3b9a7c-f133-b7ee-2b62-1421bbb3ea37') + response = secretsManager.get_secret_by_name_type( + secret_type='kv', + name=secret_name, + secret_group_name='default' + ) -# return [Document(page_content=response)] + # secret = response.get_result() + return response.result["data"][secret_name] -# def create_sql_retriever_tool(name = "sql_retrieve_documents", description = "Search and return information from SQL database"): -# retriever = NL2SQLRetriever() -# retriever_tool = create_retriever_tool( -# retriever, -# name, -# description, -# ) -# return retriever_tool def sql_retriever_tool_watsonx( api_client: "APIClient", ) -> Callable: - db_uri = "" + # TODO: change to secrets + db_uri = get_secret(api_client, "PG_URI") + print(db_uri) db = SQLDatabase.from_uri(db_uri) model_id = "meta-llama/llama-3-3-70b-instruct" llm = ChatWatsonx(model_id=model_id, watsonx_client=api_client, disable_streaming = True) @@ -121,7 +100,9 @@ def websearch_tool_watsonx( toolkit = WatsonxToolkit(watsonx_client=api_client) + print(toolkit.get_tools()) rag_tool = toolkit.get_tool("GoogleSearch") + # TODO: include more information in the search rag_tool.set_tool_config(tool_config) @tool("websearch", parse_docstring=True) From 1f05d8c853d1954d1ea831b26f0575dd4b622092 Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 9 Apr 2025 02:57:24 +1200 Subject: [PATCH 3/8] added serper search Signed-off-by: Shuang Yu --- .../src/langgraph_agentic_rag/__init__.py | 2 +- .../src/langgraph_agentic_rag/agent.py | 34 ++++++++++--------- .../src/langgraph_agentic_rag/tools.py | 31 +++++++++++++---- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py index 1358ef9a..6a397ca2 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/__init__.py @@ -1 +1 @@ -from .tools import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx +from .tools import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx, serper_search_tool diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py index 22292c87..b3ce5ce5 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py @@ -19,7 +19,7 @@ from langchain_core.output_parsers import StrOutputParser from langchain_core.messages import BaseMessage, SystemMessage, AIMessage, HumanMessage -from langgraph_agentic_rag import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx +from langgraph_agentic_rag import retriever_tool_watsonx, sql_retriever_tool_watsonx, websearch_tool_watsonx, serper_search_tool def get_graph_closure( @@ -35,6 +35,12 @@ def get_graph_closure( grader_model_id = "meta-llama/llama-4-maverick-17b-128e-instruct-fp8" chat_grader = ChatWatsonx(model_id=grader_model_id, watsonx_client=client, disable_streaming = True) + websearch_tool = serper_search_tool(api_client=client) + # websearch_tool = websearch_tool_watsonx( + # api_client=client, + # tool_config={"maxResults": 10}, + # ), + TOOLS = [ retriever_tool_watsonx( api_client=client, @@ -43,11 +49,8 @@ def get_graph_closure( sql_retriever_tool_watsonx( api_client=client, ), - websearch_tool_watsonx( - api_client=client, - tool_config={"maxResults": 3}, - ), + websearch_tool ] # Initialise memory saver @@ -83,7 +86,7 @@ def agent(state: AgentState) -> dict: """ messages = state["messages"] tools_used = [] - # query = messages[0] + for m in reversed(messages): if hasattr(m, 'tool_call_id'): print((f"I have tried tool: {m.name}")) @@ -94,7 +97,7 @@ def agent(state: AgentState) -> dict: unused_tools = [t for t in TOOLS if t.name not in tools_used] if len(unused_tools) < 1: - unused_tools = [websearch_tool_watsonx(api_client=client, tool_config={"maxResults": 3})] + unused_tools = [websearch_tool] model = chat.bind_tools(unused_tools) print(f"unused tools: {[u.name for u in unused_tools]}") @@ -170,11 +173,12 @@ class grade(BaseModel): # Prompt prompt = PromptTemplate( - template="""You are a grader assessing relevance of a retrieved document to a user question. \n - Here is the retrieved document: \n\n {context} \n\n - Here is the user question: {question} \n - If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \n - If the document mentions it has no data or no results to answer the question, or if the data is not directly available to answer the user question, it means the document is not relevant and grade it as 'no'. \n + template="""You are a grader assessing relevance of a retrieved document to a user question. + Here is the retrieved document: \n {context} \n + Here is the user question: {question} + If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. + If the document mentions it has no data, no results or no information to answer the question, it means the document is NOT relevant and grade it as 'no'. + If the data is not directly available to answer the user question, it means the document is NOT relevant and grade it as 'no'. Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.""", input_variables=["context", "question"], ) @@ -185,12 +189,11 @@ class grade(BaseModel): messages = state["messages"] last_message = messages[-1] - # question = messages[0].content msg_cnt = 0 for m in reversed(messages): + msg_cnt += 1 if m.type == "human": question = m.content - msg_cnt += 1 break docs = last_message.content @@ -198,8 +201,7 @@ class grade(BaseModel): scored_result = chain.invoke({"question": question, "context": docs}) score = scored_result.binary_score - # for m in messages: - # print(m.type, "[messages]", m) + if msg_cnt > 12: score = "yes" print("number of messages",len(messages)) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py index 3a5e0f4e..52945067 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py @@ -8,6 +8,7 @@ from langchain.chains import create_sql_query_chain from langchain_community.utilities import SQLDatabase from langchain_ibm import ChatWatsonx +from langchain_community.utilities import GoogleSerperAPIWrapper if TYPE_CHECKING: @@ -37,9 +38,7 @@ def sql_retriever_tool_watsonx( api_client: "APIClient", ) -> Callable: - # TODO: change to secrets db_uri = get_secret(api_client, "PG_URI") - print(db_uri) db = SQLDatabase.from_uri(db_uri) model_id = "meta-llama/llama-3-3-70b-instruct" llm = ChatWatsonx(model_id=model_id, watsonx_client=api_client, disable_streaming = True) @@ -99,10 +98,7 @@ def websearch_tool_watsonx( from langchain_ibm.toolkit import WatsonxToolkit toolkit = WatsonxToolkit(watsonx_client=api_client) - - print(toolkit.get_tools()) rag_tool = toolkit.get_tool("GoogleSearch") - # TODO: include more information in the search rag_tool.set_tool_config(tool_config) @tool("websearch", parse_docstring=True) @@ -118,4 +114,27 @@ def websearch_tool(query: str) -> str: """ return rag_tool.invoke({"input": query})["output"] - return websearch_tool \ No newline at end of file + return websearch_tool + + +def serper_search_tool( + api_client: "APIClient", + # tool_config: dict, +) -> Callable: + apikey = get_secret(api_client, "SERPER_APIKEY") + serper_search = GoogleSerperAPIWrapper(serper_api_key=apikey) + + @tool("serpersearch", parse_docstring=True) + def serper_search_tool(query: str) -> str: + """ + Search for online trends, news, current events, real-time information, or research topics. + + Args: + query: User query related to information on the internet. + + Returns: + Retrieved chunk. + """ + return serper_search.run(query) + + return serper_search_tool \ No newline at end of file From fce6112a692bb10a86a13adda41b0658744462bd Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 9 Apr 2025 03:23:54 +1200 Subject: [PATCH 4/8] commented out graph img Signed-off-by: Shuang Yu --- .../README.md | 2 +- .../agentic_rag.png | Bin 13400 -> 0 bytes .../multi_source_graph.png | Bin 0 -> 14353 bytes .../src/langgraph_agentic_rag/agent.py | 9 +++++++++ 4 files changed, 10 insertions(+), 1 deletion(-) delete mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/multi_source_graph.png diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md index 7e66f24c..99eacb5e 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md @@ -21,7 +21,7 @@ An AI service is a deployable unit of code that captures the logic of your gener The template builds an application with IBM watsonx Utility Agent Tool for addressing RAG use case. The structure of RAG graph is as follows -![alt text](agentic_rag.png "LangGraph Agentic RAG") +![alt text](multi_source_graph.png "LangGraph Agentic RAG") > [!NOTE] > The template uses predefined `Vector Index Asset` as a source of base knowledge for RAG. For more details about `Vector Index` see https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-prompt-data-index-create.html?context=wx&audience=wdp . To run following Agentic RAG app you should set `tool_config_projectId` and `tool_config_vectorIndexId` in section `deployment.online.parameters` in `config.toml`. Moreover, to help the Agent correctly choose whether or not to use the retriever tool, a description of the underlying knowledge contained in the Vector Index Asset can also be provided in field `base_knowledge_description`. diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png b/agents/community/langgraph-agentic-rag-multisource-retrieval/agentic_rag.png deleted file mode 100644 index d34b91ab4c030ef97bd198e685e65cca66168cfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13400 zcmZ|01yodD*f%!2ag_HMCJsX5fdEnEG{0jF|qTK#0D;7cocA* z-e8Mc9j0%N+PfY}hFJ*FV%#;)wtz#F>Y2|UisZq%L#JZr;t*tXT2PDUeG7pO7`vZ3 zpF|rK>(%YB^cPN&n(=h6YwQx@>q&2mk1hMXUgnCH?Y_=@^^U87gL^pfsZODBi@t=f zn7TBzs9=o^p6%>Vm&K$UkwJ)#dam}9Z;vr$uL6UwWuAK(b4Gh1mJub5#TvU?eZ=(L zm+-ERg$#%6Nt(gG8%cMHf64X~zUM*8&$-uOKiIvz4ZNKwKPRKe=vrr}yy)qC^nEP) z^d&N)v{y-lyt2p3-1%7hkmh(oK6CN?gN$CY1;SZ`F|yTJ zQFXM~+x{+X=jgN9w+lG!2+78kb!eQ`w&KB4xn=X;iZZ&{S_`F5&4W#m%9)RH@|(@z zcX~f5x%v9NwCIEsAatpV2;<^A^0KbSp04_x-d>*?H#py3oz&LWzB{ z-*DAeiO`4@QNefhBy)81*RLSvou7eN@87?d%^q7>kz!}J>ie z9l>K`V}e#AI=Z@&-hbcrMBY+-_;!R)7e6^M1T*Vp+c@rHSy}P>$?z_Iec4=IqCDxPF`!=t)JgzGd zb4bbU^X;cWOw#Ai75b&`C-cX5-I$m%mzzCjr>8L>2XHtB#E6F)Wj>Lo^iUy&5FZ~C za&>+EGL>%)alZc}L`P2#eKx6H!4}(x1;N9{yuyv@q8R&JMI4spHKqPI#0#^eCLIz0 zrU^f!%AzOozM!R?oSc`p_cQVONug(=qPN%Enav(>a{LgVR+Azf(7&0IR-f~rp63{4 z491V)PR10mf2e~oDjH@cM!__WWj~jal3In`z|VFkQ+SNOrledtR!jO`&`WqZ9WFKE z64Q&qZoMolEEY@rq*j#=k#tX@JIy>FQ81qW!M7&Qp7Ghl#l<~ZsNJ9VuJZWtV0u%w|_SVR#sMccz8f}d{C+KEYp*_3?sS6g-q(w+HOl0Ziy`| zEq$>}SP*L=18eJ@z3CD*awS(+LBD&9(R743ctHk+iXpP`85#CISq`n{Em}Cv2V!>7 zpn+($6L^;<=TJ)%oc5{1(p=4ZZA(i_cXxMl^RMfLa`|CTW~X9fy5;yY8x2X5QRe6?JHPO3$?b<@_)dtc%H2Rfq+#t+~2QXZ5gfn-RE-I zlLhaqxaZ*od@(U0VW!M@e{HSO>%<~k<4QIVd2`7mY%{ge>I+5Ry4s2wok?%aRKi3v z+Eb)7H&)}-ULQu(KAby6&LrqT@8epfPd&3MrS=WOnD&$t^z}Dtmb1B!mgRECYhvD*O7o<+ zHZFN&4w~^985=LQmYhZ8{El&}8c@TYMMyTY>HcC~T!cr&)pVW5Yo{|9-DkIRT0nOY zhEs-zECl%qlrnS#oSD*M;-08Rg?S<&kQ0JsCS$T$%908XY+VsqC%#$v;g< zJGS$iujc$QtvF6(bL8Ll{e{FE_;6wb+OHEK=OmU}Hb;HW68dHhDm=RPj6^jC*EPr@ z6;ctnu9rE5$8B~~LMcCGtQ~(y2jZsmH0rTcx-Q@1daN&!DM29t`i0HTZ4vSXSJ=)V z0Z91Tatmh5Ye(llFugvGZ1DeRHl;(Y%t0p?w2P~4TE^4B$vK#KO25Nn!u2g+gktO} zhOjjTQf_B06j}4SAWl~Pp%+TJcTLlmWQ`=!#q6|cB85z={S|GAaHmal&WrNTvN}&R z`nekS@?Mn?;Nyo9GuU(pU_ktE#rQDG0xY-tkMZB0GBlmzf0{$QPTJesbKjr&o}X_4 z4}Toak7C`$`3g1NF7WTl8yWl2)5^ynbWgXQm7 zzqti_%emm4M*q0ExEoxhQUWlFeq?5M=n`7VuKyg@;&~Y~PM=x}s@>4= zTQZOYoc{WCC=cC9uhmYRt?_8%#uoF95beO_Y|9?NdlN3i7Qv+9$yj9lYImyXX zPm+o!cUj3JqM`^wWXG+AK<3bIo*{mV^o@V!x)m;$^YtrjwnpK!jV(BAY)UBwns0tj zaT9)d=9*t#?zpJ_N&bzOm#7Ehm!PR~hJ=I!eXdvg^|(|?r6-b_;RNci=H75GSM`p33JSxJw1fn7vGlx4uRC)yQYk=rP(J;rCtlV z)_SJoKBA~Xm-OpNwLG}r9yhlRvQGMr;LMrWt<19>8@2~|u-GbAO~Iv#i%tuFbE_> zHLR8(8C!t%9=9<)ltK%d@JbOGPE_>oMgL#mZSUV=`Cligw(RyCo1y+pwSDo3*Qwj1 zr{jL<@Y0~Kkf5yGcKZGyRa-l9eC!L&TniIlcdW2349Lzo;;0QR@KBH_=xqE=?~CY2 z@9kD@E42b~F)<8?0I#Wp`=0)bclX1(qN85wSNd_M4dXyqM`HZF*Z$&|BR4szb)Rfz z$#m7(E$ki~R5?$UG&YhzARyI?rue)zvpPS9O6H(4P{^wjim()J!_&#Y#KpQcPh{_O zF!ac=)eY78MNh8`4MS^EQ_nKNZfPNq%vS>g0}JOTF=J!lSkP~Cb?2=IwqFK(p`k}P zle-)!*X~v5ad-K)ztokXre+6kA2BAx`>*c_aZ@V&^(&&O|byWLo0c^+DBR7ni^ z{RiIc(t}W!`e3#B*WJP45E5Vl!$@RT!-X_7HipI0=;~h)LVj+azIPJ~9;m7Jl-@2m z$3q^#876p<*F7oCU%!3?K;gTVi>T3+nWnq@=F~vMkK|m1J}ECRYKR#h%{S<%Y12mS zjLP${kC+f;l_)bLCKfu4c5FnAImw*jeTl-(CA>{CMF8dVrt2b*<+;AqPwTg?%{l{oY&0vqcF8m;HiJ}x%UKGReUuFql0q{Nj==_jyrR2rZwd|WIG$bI zHZiGrAO#b+jgUPVg?ZrwW2j8qaNVG7x-F}B-4LbSd5;sV>bQqH$V~75@c9TM#jbtD z6(Z~W$5KQ>*1S?5Ou?NHb;D>^m$IKwjiRaFzhOi~?l2hYm_sZ>ZEh~$tzyJhvd1Em z|HSUu@2ocJN#3ccS1F$vh;uxD6@@A<_kc5XktO z^_3Nr=GJD-JI*cp<+@h|v+$Q{YbRd$nMtXsQ&Uq{h|o;|9eJT{@%9H)dpz`|8I3an zR)5cYT8(&Iot!@UOCkn41g+HbzYSC_&J!I7#%pWK@h7pw#kgofy6Pg=;&3Wo54%vOTj zHly#lbRdOW2u&C6e&TV+VgaEgpv~NaXwwEev^%Tu)v_;XyX_^pR(tAvndihuau!-T z%F>q($%^HIXLsQ_ux>;Dut2w7Q)tNn_2Ey?Eb+!_!dKy|HoBi6Lb@d{hzwe(B2CB6 z_5I|gNwzeT^P2SE2|=8LubT?TtshbTeCy$y7l8d;tHYwwTIjT-m}iAcESQ|MlYnui z=j$a&?>7J#&9$@=YBMLMrYM=19N`5uA#>*>&q%RBhM{D{M!(h^oR#fAQL%c=%UfPt zEW7=h5`XjLPaiio_m0HK#W^Q8_i~eaNxQ$E$F@5WU;=^IznAtTmTmMwe9Jc zI;Qk%a8UP&E*gdWfn=teRWF&Qjqar$!OsrXDtcR~KXd42--zVmJbOhthJer?5^92ysc`nDx%j@>`bhO@KxyoxmWE!T- zngDQ2TpVdB!+YFXgN&3EYAPzrc?)~xcE)gcO(uAfl9E!#0)e(PsgTEk{$TR^hlqjA zzXu0)=|lI$g5-057}g&GW)jDfH0l&ijYd-; zLNPS_>j14UbKw#p4Gau~XrpU0EikF6satk&!$xv79xX312RA#0(7R#U8IU|lvJv@O zcrDAdLAU@w2i=%sUkn2vC_ArMl237UKgs9LYZPBut#yW^@R}Z~-Iar*0p_p-kij42 z$J%>!faby!S=~!imuhs|)k<;Hdy+)uj;j(G71ewyMns2o^h-F5r-_d=b$ znIDGDe&RSca_s8g2qAOLo=34zl-J(WV~DhY!2+PK`+Iw$^lE@!{Yv6wU|?7y+ZxYR zsIIPNBacW-oCJKDn%h9`yVji`G|mZ#fd5Fj2mGttgUb4PCP|+&&hi!u5BYE=Of0PJ z;k4PQsg3pZiI7G9u_Hh(qCh6CwYk@l`sK@)>*1%XT(7HGpFB}!C5NxJqgyXmZV>zB zk12n7u72=5-5M6QodImKAS=skwe5q!j|=cJ>-(>j~54CkdeUv3Fun;IlXf*UmYJG5869DIk_+4bzH1l0_G=E(syQJ zBH_!IXa1<$)KnUE_0hSxIq*0%@^Y0tBG3N)=H?~}h3X0;xjZ`~Bq8}nxB>Z$MWyT! zTU2_1E*Upd|Iz$nQqIfCxj$QOy3YZ&$8mORRh0l<(1OX{WI?Qa?t1_Y4P^oO1{vpY zxw+i9nLTm9@56@=etu&}^5vfKaefYt0^2v3pDvY(r)_e_`|T5D@YPBRwTg6}= z^S1JN0krzZrIDJ)NKs8Kl=+c>fXnb#VW&$aW{;zlO}>|h;5}cR&ziQQrF`yNbIYd0;=Y-IbsiDzxcQiw{jRne zHGqzej)obI1I$VrJ#(Su;J_2xcl!6Qjp4{}+SC30{k4Vr3=A1@aT=PMfromPgogDF z_Gx#CSZH?oEGhvIHZd_#Qi?DsS65YS0gMvhU|L#Q7gtwpEiD`(+NlC{ra);@CMNWv zWBYQ8xAr4S%eQZhn%v&^e!9kCBC`D8ckSM&ajx61!MsHkOz+*6>58uZ6P_Z zWhn8#+X|4%wwKAIIWU`yy(eY?vLTlp!+ZyUii4!bSGF>%q_wfR|&>wUZ zh$>hF0N3TsEBd}U-XW=yjBK0nrub97=0fCUByW*FD61*VR#F^UtH# zh=V(%vo%Q7Fz#xgCnhIN=L8ie@PYQY7RIEZQV@WvrKJT!>~ehU#UA68l3E!UxNFNh z)-^m#bdBbmN0ZTEPPKz2^7`>Dh7>;yVShU>#@S+{Yk?6@-vYteBW`Zv8f!AyH<&vq z|E5KcT&}O9Lxw$(MTq?dY7xB3z(&EY8Zc|T>GCXXIMm<6)3e_0Ry8Mh^+KDKTv$W| zKScJs)?IX|&J(aEVrosT`JC6~D)m2gleZ&6!ou3e>U@2DIoR1Pw#j@dz*IaJx!tRO zJCIOURFJB=1)>7~Ii93ihFHikRCxH#WP!Tvy|a^(FT%D|Giuq`!5tMLm$QJ` zf!G%IG}+VR4Quv%i??9sTc(B?UIBqB$JI6n1VoN++Sk7kVHN28U$^St`3mnnf`^U_ z55H7XgI#Z?{Q2`|-1|YW(x$kXpN4$NG}zg!+jqnYR)Yr)Ix``IjDw=|kT}b%ejv%;$3@~)>J^Gb7KtAiGU9n>h^%5^?;$T+_}2`kNj~bNv&FPF2)~aIg|X7O(bc<@(mk7iuaP1ejkLq zq;j`&cC*?QqDfB|bKjc+**#wW!GwD5M>hj5k^u7%8OP62{Q8JlYazT8h`m3bteoZW z*O23G)*>dxYtK*hF*^~tmoi^h^x~A>+KeiB)h_Y= z*UoEK_JhStLSB9*sf4PV(@Q$qy*GU!|Cr(Y)GE1EpJ_Wx*xBRu66$v@dvo1VXttQP zZ^;^yCcurz@T{MjoyC9j;8MCZ&CT8Ax}VUI%zTYU;+}r=G&ED? zM*;P#h{Ce6EgKI@GqbqNOnIX78=9#_4Snxm&UBg zujtze=|yQ!9cFwI{@<9WXy<+2@5E_9q~E{4xnGY%Xw4C*41<}pw_(Ar&~|Jto|ngG zXJCn7L%L%!oRGb`ULArr2JEqYQJ-j*$Da>!ijggoaFRN#)E-`i^xbgK)*Ji?W!?ew z4af@Cwqsm2?N4e}=BPqsO>~Sz&DZ;9)Il^hk~KQ`_)x)rXmF50!fS5&U}#*kl8Z{E zNT=>bqmpL4f!?sHy4rE2<$5d4@oTNzo7;i^%|($*9hDTC#$FPrEScv|+beV7Vf4h* zkl)+eOf)oZ+}n{UDWd=}q;SEeyPs#IHznj#zWcXyN%^dI6uxT(2j2(_O*tw*Jxkk5JYO^^TneQ&Q{T>KdW-?_u&MqyTU7bAlk{TnM z%pZAG^f~hb3a0674mkg~DREnspMy+?_LYs@!N4SBy4hr&f?gwvO$&YraCD{+*aHe-AYKC
L@C?mo*a8;(`N576Pm$7@|kBr;w<0kK8~kUcfE+&=5un+S!tcJ#l8SX4H&w9x-gOUK8@ zzzcdf*W%^(iAR`Lgnv!MMMZ0(jcqaIiksq}Ol_yW6nS1$R#a z25<$S@W1#vT1`ziaoK&v`{dciGTrzy=D`OkgLJgCarzIUpxp5M>%G|O9)Spx$1fhEcv_Gt$}b$xHg-nxv}D?yI)0C*!l?)P`};>m z(M)VSD3O@rza()HAyF= zh?EozxT%Up+dzu7exr>vefN$HOkVWMbAQ0-|II$QM^{(Z{C_T-#ahi|IYNt3``@MLjb-vj zoW1{eLTQhc3#1I%c)5(uau`rMj%NeJv97}IalR@wsKvLPb;5=%jsir`75Unu9Ri`m z`Bw{o4t7!ppcpVgYA*c%0MN_`kgGv=2-4G0Y0N2V1?pdgl$dwqe(A1TJVdTW-s5DH z^ub0S93A=ZjIn@FQko%)wSi=U?K44se@`(93gZT@;X=)ONjZszYH1n)idh63E9+0* z(c9Zw%aQbm-^6qsR0wElqwBVdXu47&do~rCf<(U*UBase9ZHx=DN1sYTa){NA>sOS zZ&!_xizkzc{N1WApHJT$mmr$+Lry~)4>u;$;M-aXErqTLY=?WJ{}r})y$Wa~wL zxWeLAxH_3Ok)sglOhEcB{^;&f(^&tSw*08{AHH5dLCZ{9n`~!!s*~Zf8cCfRXNqc( zv&sEMWq+xje|Scl_N=KHrDvMoDHZ+{W#;-`nC%IPf5}mSY#VA8hO~V@<9+oe&J%mP z0a1}8AVkjL=7}oMyZ$3DcaT_J(wXBFHaQOD^}~Naw8-x%zlKtTI*`|Yg+xmtLBbFAmkBO z%}f_tTPu$5lS1D%azXxKvH~@Rl0vROP7ThLcR7>G;W|zURT8i5D=pT^ zNjB=;h&FCaxkOO6>x0HUJt0gVQV%wE{EoMgNlBZk>=bQh&wtJOquf3I>^l+>-giNx z;2&<L`Fji~=+Wb?nS zOl$7jDXeVIxV3ed*f`&>i=lf;_Rm$W-T%Wtu*JLFc$x^3Ebk?3=|R%L94h`h3X=*O zj#6i}X>;A~%?TM)`1s=DkfG%i9{Zh}{3^kS2YT68Y6*%iQXSPpn?3E^h?}0%Q7Uec~Xv%*t%_%T>Wr|n9TSx(F!B9wwH%MAV~6MnL&3sM;qm@)PSJ2YG4bH(Q_rYd zGA_Ko*O~9mY~RO2AfiSN`y9t;DTs8D4g|6?cWY4c+$olm{ApLa0Q#xs9Y5V7ogKHP zk4ora8B7`QW?c8nB^a4dGUc<5zP1e5GW#B7`GGVcK^vF%= z#nH4EUW6m*Kzqu_KmyAAwYKIHtODn&NMPApfycL4w_z(M7iB*Kvg+y^8k-2{#O<2B zB%~4tB;s6J;9+p$fxoAxz({Fd@ijaCZGOzbOCz7UC0DOY40@wZ{9ipNh z7N0_C0pTxKsL}i-farkh%B)QSlSuTH^;#`VPNa6x&>x;bp;0_V1IYTV;PsrOUj4)RejHE?`)$)&m9M| zRz3il4z^HQTH4`C^Z9UnW-MM*X>l28)C(u7?4>@E$Vh^7pAY{(VAhX)+nkREuUhK0 z9jd~$ug^CD>htE*mS?1lfSSkE!{za#D-MVGuey%FUV}*-zjSp?OiVm2j2|CN`5|mf z8!dlhcUiw$;CH@)yEtW&6c#o+$Xo99ex%diP)t)DH!hOZb9yY<&fD(a~1exQHGAQNc+2MTA1dS8vLF?mVA6#L^^2OeLk#v~;ror9vI zmuVtjYHQ|hjeoq_KNAy2K^5LUwKriSooh!k=CHQNVbosVnEE5#frJ?=B>;U|tB>^c z?URoOwMTT~0OLEXG+i8zx2i)?zqCRwg>rIpySlpK^$ki<5pu(;AJChvH}%4_wSZtO zJ&PhI&-duH!VEA#K9A|y%LHQ{VF=fniBH`G)7NfRj9Ri1OgF?BS&BeSUszh6yx;eENgNP zP=d1AfQ}Ro#6{FeAJczCUh&<#?{W`hEaqW117?~;S40Gn_uXidhI6xzv#w9K(@dD` zzkfh_UDPxQNbr0zk1CYul6ld7c;P?tjjIZQq|2E3y)`InHfIcKxqv$or|*%+G`aEx z#aul<5kr=mVD!Z(hX7CJO>2Eq(*ouR)Kx1@*yhhzrJAZ*EaTQrZST6m1j1#rCh5_g zGwmWBLY!c=r_g3WiuQBOT&E9;sYIHn9~OD-eD4xx>9hR?BenC4_US!!CEI2qz;W(&;=F6&j!sc|xdLO$SIE9XPfrgXb(dZ6KdzzOffRa{`Q;S&%5_5Rb+HwdD!p#iwegtojI zIfaFf`1nX0B{9xUFE4=*-UU=fMMXtv8gJ52$e)y-KYxBp^h@m6Su(hXvB#7+KpE9D znhEV&AQPgI^l>XN5h0U?LZrbRCMJwCCi)p*5I_oIU1T@ta7SIf;xTSI10DbeW`7EOBI0xU-N!a%$J%U0livv1y~x-lkJioPa8dFcL9uz$%zSIGd=;prVMEd zq~0qXHA_o&(5nzo*ysMklOq9!g-blO>o!|v+_gYfQUSz7o~0M5D3bh&isN7sDNq6@ zin+*$5x>U-$pYG7Fb@> z!)#|{S5$TedX*MS_w*2y27(jZ^3k;Jo4@W+mFz2&gcmc>vm$^WWmsp|u@KMWabAfD#`7L_(S2DLD3U%Z7fCpY?P^Phx1%`4yV+d@e-UYH# zMb-rL?KYH(Ym91-Y3QgOZKAJ#b+PF929zzy$IyEt5$+!wHRH|15g3pdMoHz|aVj1= zj^UUe76foBPT&@m6%|$5VZD1iF);xO@wiP&U+&^U=IZPXfxjm&k5lKsWms1VFF#K9 zVq#(%gbr9o+09q62?|o6o;`SAu{HF?S_%n9fA{X)MD~|K{?of|KCLUtqgAyCTo9AK z4Gj%}cLBuW{d1op9iN*E`>AiRn+tevuY9&fYFu30*RMYNGu-<N{`qzz(1yMLZrqjV2X4gc*RN-MlkI1qUV|R{?d&14GWL~^q0siCq9XTD z=9Iy{XgaIbzWIEZQ}z4>#docUkqbC@dTX4IG8a`}cennob6wGDi}z_uYpb_}iS0dL z$v$;lky{(DcU%p9zTFuc>WMORRJIvJt^(&12=YfOt(;U*z!GkUAz{dKy%MR)ni{vs z{Fi{vfhx>_fyZKEKA?p3RW$k?!N2m{k4ZMpxoSLtJE}G+i5LDnbkR?el*{7wYs7dR z9ZSTub$d2lyd@a-P5D1xUATb?PS31ozI?4duIZ9w@9_AD0?$i0wE>mVkW;wS(lF4H&0u{Lrvhdy^r)>Afih?I+%`lU*+w7&D)$x&}s9N6S?8clIY?|^f zU5RP>cMn>zCyzSS&z}e{3zKR(C|hWr7dl8|Lxo1NfpMeMUXv?J)LnJCvvgM%Q&VqD z$W5pm9j@jl)47v^_`n@9Ty1`0wnvbLAT}q8dSO5i!S6qMojWgGx%qWAQo%H(#qjUm z12$P-%pJYgg_JYWYOP|k{G`;Y+27`^UXWHXO97MPMwMdre%c17euwk#717m?-Q-6I z$#&jcf%|si1TDqPq%mz5*PeM#8m|jiy=IS2+`qW;-fkVuox*Pgw=eZ`-_EY6k?^Fc zXGhv1^M=Kga+7-=O2^4Xb-8Xx_*+Zah?kvndOz51p6gdh9_ieeh?b8mG_eH*+USLs zwPJxKwOfRwd7}+JJL8Ee7D^ext-fc4*SVcmT`4Q8lFmj$oC(RHVX>372JfWHvw4TT z44IuUAfI1Ji21G&WLFFgjN49JO~3j})H^;{R;B~rFfTspb4Ql&YLC;*{5|gMaV+1W zkBTy>dbfPCqj@@tyxxTSZvR%%d4l{^Yr3?I>0zg~T!oT*X>8s*orwW?QhR$`ZrDiQ z5jq`4-E!6u-P}I-He5c!xXTQZgCiK&?))QDnRxv5tNF(7T7!;DQVfDV|jfh^;O>wDSO@vy|^F9zg#w476SqPxhjMIz`!D=zD>k9twn z&-)cIS=BoN5nosy!OjJDFrrlIwU8x0e2MR$eeemZhfRo^c~uu0xo? zNPz0fkcBe_giv1GYC@QnE%5|evR6@=6mW*4Xv+_r+%oq%xlKXR||G;G^Zq3}H4r|7Y8(dPBz_wF>nn?Snn z`bw=v9)%M6w3ftv;p%Oe8EuDNS{g(JbL6NFWxQMHCZexf&fLApt6~>#I}K=i!`_qj zW%R_GScTf}8)7!)hNNw8=l3)3+ph;{9BVO?v_g6VzC?V2Qk|EGA7lrMI`jf85L+mp z^h&8#l)+YugJsu4*fuDflg7Y$K>s%SNh$Itq*jMPVB)s;e%YcrM0yT8Z1v*RVxtGm zx1+wUeNNkj0f%>d(m$>9CKk{^i>snte+;-dMmG;0+Ha%mvmud{!8jhL3#JSV5(}+) zx_g_^e_;=Ahoxv&;T#Z1z)+%WQTp!AG76fjGm|%4f103IFiC@9R`)a-3nDt_tIro6 zpv8e1hf{YWnfMU()^5&)LjW~1*OJpI$A^; zgY4WgpJnf@BALKHyF9ta+HzpxQGjEsFeY6ttg|`ukTRAAWGFsC;sU!t<>=HqNOnsVr-2R-jNd1ZL5%CQ0zAly?7)v`f`dLPrr zTQ+cDCy2dJiS{~)G5M?}5{^Ad0?C@BL0wgv6!A6Th|T|Ot4YRr@h0MtSE2Ec-8RpX zngr792|?2Ah{*j6%KieY^2@Af7* z{;nI{$&i_}A#!7n9(c1Wl+h23WOozOEt%L8CLR4IgAocu-Jhgw!G`sy)9@drocNFP z5_a!tDdr072wBcZR0a*?JA3JTlZ@ub5`30?|9UYTCP`&6gjN&_`oAi?hS3;!i+Vjy TCoNWB_8>|x)a1%!&4T_P90UIH diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/multi_source_graph.png b/agents/community/langgraph-agentic-rag-multisource-retrieval/multi_source_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..94a1f03b02f1c8fafad71102dc320f5dc9b86888 GIT binary patch literal 14353 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 bv_yq(WK}BJh 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 N@5JTAN<{Si{}1!kgw_B6 literal 0 HcmV?d00001 diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py index b3ce5ce5..4c1c4d5b 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py @@ -262,6 +262,15 @@ def get_graph(instruction_prompt: SystemMessage | None = None) -> CompiledGraph: # graph = workflow.compile(checkpointer=memory) graph = workflow.compile() + # try: + # graph_image = graph.get_graph(xray=True).draw_mermaid_png() + # image_path = "multi_source_graph_output.png" + + # with open(image_path, "wb") as f: + # f.write(graph_image) + # except Exception as e: + # print(f"Error generating graph: {e}") + return graph return get_graph From 8b55bdfdef339c6226c4d24f4c0a1cfed7f0af47 Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 9 Apr 2025 03:31:22 +1200 Subject: [PATCH 5/8] removed some comments Signed-off-by: Shuang Yu --- .../src/langgraph_agentic_rag/agent.py | 5 +---- .../src/langgraph_agentic_rag/tools.py | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py index 4c1c4d5b..31a8ad25 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/agent.py @@ -229,7 +229,6 @@ def get_graph(instruction_prompt: SystemMessage | None = None) -> CompiledGraph: # Define the nodes workflow.add_node("agent", agent) # agent retrieve = ToolNode(TOOLS) - # workflow.add_node("rewrite", rewrite) workflow.add_node("retrieve", retrieve) # retrieval workflow.add_node("generate", generate) # generate answer @@ -254,14 +253,12 @@ def get_graph(instruction_prompt: SystemMessage | None = None) -> CompiledGraph: ) # Edges taken after the `action` node is called. - # workflow.add_edge("retrieve", "generate") workflow.add_edge("generate", END) - # workflow.add_edge("rewrite", "agent") # Compile - # graph = workflow.compile(checkpointer=memory) graph = workflow.compile() + # Generate the graph image # try: # graph_image = graph.get_graph(xray=True).draw_mermaid_png() # image_path = "multi_source_graph_output.png" diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py index 52945067..7fa93934 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py @@ -23,14 +23,12 @@ def get_secret(api_client, secret_name): secretsManager.set_service_url(service_url.format(instance_ID="insatnce_id")) - # response = secretsManager.get_secret('1a3b9a7c-f133-b7ee-2b62-1421bbb3ea37') response = secretsManager.get_secret_by_name_type( secret_type='kv', name=secret_name, secret_group_name='default' ) - # secret = response.get_result() return response.result["data"][secret_name] From ef3f1b8fcea67212134550171fa8bc876f247f9a Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 16 Apr 2025 00:02:59 +1000 Subject: [PATCH 6/8] cleaned the code; added docs Signed-off-by: Shuang Yu --- .../README.md | 27 ++++++++++++++---- .../multi-source-diagram.png | Bin 0 -> 144737 bytes .../src/langgraph_agentic_rag/agent.py | 19 +++++------- .../src/langgraph_agentic_rag/tools.py | 5 ++-- 4 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 agents/community/langgraph-agentic-rag-multisource-retrieval/multi-source-diagram.png diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md index 99eacb5e..f6ea5485 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md @@ -1,4 +1,4 @@ -# A Base LangGraph LLM app template with function calling capabilities +# A LangGraph Agentic RAG template with multi-source retrieval examples Table of contents: * [Introduction](#introduction) @@ -26,6 +26,23 @@ The template builds an application with IBM watsonx Utility Agent Tool for addre > [!NOTE] > The template uses predefined `Vector Index Asset` as a source of base knowledge for RAG. For more details about `Vector Index` see https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-prompt-data-index-create.html?context=wx&audience=wdp . To run following Agentic RAG app you should set `tool_config_projectId` and `tool_config_vectorIndexId` in section `deployment.online.parameters` in `config.toml`. Moreover, to help the Agent correctly choose whether or not to use the retriever tool, a description of the underlying knowledge contained in the Vector Index Asset can also be provided in field `base_knowledge_description`. +Traditional RAG has the pain points "I have a lot of data scattered everywhere, I don’t know which data source the answer is in". This pattern allows the retrieval agent to make educated guess which data retrieval tool to use according to the description, and if another data source should be tried if the answer is not relevant. + +The three example data sources (made available as tools in `tools.py`) are: + +1) A SQL database +2) A vector database +3) Web search + +A retrieval flow looks like: + +![alt text](multi-source-diagram.png "LangGraph Agentic RAG multi-source") + +- Agent select a source to query +- Check answer relevance +- If relevant, generate answer +- If irrelevant, try a different data source for answer until all data sources have been tried + ## Directory structure and file descriptions @@ -41,7 +58,7 @@ langgraph-agentic-rag ┣ config.toml.example ┣ pyproject.toml -- `langgraph-agentic-rag` folder: Contains auxiliary files used by the deployed function. They provide various framework specific definitions and extensions. This folder is packaged and sent to IBM Cloud during deployment as a [package extension](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=wx&audience=wdp#custom-wml). +- `langgraph-agentic-rag-multisource-retrieval` folder: Contains auxiliary files used by the deployed function. They provide various framework specific definitions and extensions. This folder is packaged and sent to IBM Cloud during deployment as a [package extension](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-create-custom-software-spec.html?context=wx&audience=wdp#custom-wml). - `schema` folder: Contains request and response schemas for the `/ai_service` endpoint queries. - `ai_service.py` file: Contains the function to be deployed as an AI service defining the application's logic - `config.toml.example` file: A configuration file with placeholders that stores the deployment metadata. After downloading the template repository, copy the contents of the `config.toml.example` file to the `config.toml` file and fill in the required fields. `config.toml` file can also be used to tweak the model for your use case. @@ -62,17 +79,17 @@ In order not to clone the whole `IBM/watsonx-developer-hub` repository we'll use ```sh git clone --no-tags --depth 1 --single-branch --filter=tree:0 --sparse https://github.com/IBM/watsonx-developer-hub.git cd watsonx-developer-hub -git sparse-checkout add agents/community/langgraph-agentic-rag +git sparse-checkout add agents/community/langgraph-agentic-rag-multisource-retrieval ``` Move to the directory with the agent template: ```sh -cd agents/community/langgraph-agentic-rag/ +cd agents/community/langgraph-agentic-rag-multisource-retrieval/ ``` > [!NOTE] -> From now on it'll be considered that the working directory is `watsonx-developer-hub/agents/community/langgraph-agentic-rag/` +> From now on it'll be considered that the working directory is `watsonx-developer-hub/agents/community/langgraph-agentic-rag-multisource-retrieval/` ### Step 2: Install poetry diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/multi-source-diagram.png b/agents/community/langgraph-agentic-rag-multisource-retrieval/multi-source-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0e09225ae8d9444aee9ac0099e4abdc299c6f45d GIT binary patch literal 144737 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 dict: model = chat.bind_tools(unused_tools) print(f"unused tools: {[u.name for u in unused_tools]}") - system_prompt = SystemMessage( - default_system_prompt + "\n" + (instruction_prompt or "") - ) + # system_prompt = SystemMessage( + # default_system_prompt + "\n" + (instruction_prompt or "") + # ) + # response = model.invoke([system_prompt] + list(messages)) response = model.invoke([query]) # We return a list, because this will get added to the existing list @@ -125,7 +121,6 @@ def generate(state: AgentState): messages = state["messages"] # Most recent user query - # question = messages[-3].content for m in reversed(messages): if m.type == "human": question = m.content @@ -159,7 +154,6 @@ def grade_documents(state) -> Literal["generate", "agent"]: str: A decision for whether the documents are relevant or not """ - # logger.info("---CHECK RELEVANCE---") print("---CHECK RELEVANCE---") # Data model @@ -189,6 +183,7 @@ class grade(BaseModel): messages = state["messages"] last_message = messages[-1] + # find the last question msg_cnt = 0 for m in reversed(messages): msg_cnt += 1 @@ -204,7 +199,7 @@ class grade(BaseModel): if msg_cnt > 12: score = "yes" - print("number of messages",len(messages)) + print("number of messages since last question:",len(messages)) if score == "yes": print("---DECISION: DOCS RELEVANT---") diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py index 7fa93934..ef366118 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/src/langgraph_agentic_rag/tools.py @@ -16,7 +16,7 @@ def get_secret(api_client, secret_name): - service_url = "https://a14f50a6-1721-4bd9-930c-403264d61ec1.au-syd.secrets-manager.appdomain.cloud" + service_url = "https://{your_instance_ID}.au-syd.secrets-manager.appdomain.cloud" secretsManager = SecretsManagerV2( authenticator=BearerTokenAuthenticator(bearer_token=api_client.token), ) @@ -135,4 +135,5 @@ def serper_search_tool(query: str) -> str: """ return serper_search.run(query) - return serper_search_tool \ No newline at end of file + return serper_search_tool + From e93f71420f4ed41e4d4ddaf78f80254ce3627f0f Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 16 Apr 2025 00:11:07 +1000 Subject: [PATCH 7/8] added author name and contact Signed-off-by: Shuang Yu --- .../langgraph-agentic-rag-multisource-retrieval/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md index f6ea5485..f8434d0e 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md @@ -44,6 +44,14 @@ A retrieval flow looks like: - If irrelevant, try a different data source for answer until all data sources have been tried +--- +Author: Sherry Yu (shuang.yu@ibm.com) + +Date: 16 April 2025 + + + + ## Directory structure and file descriptions The high level structure of the repository is as follows: From 580a401dc20ae3f71ffbf8edd3e6f6feed9e6131 Mon Sep 17 00:00:00 2001 From: Shuang Yu Date: Wed, 16 Apr 2025 00:15:22 +1000 Subject: [PATCH 8/8] added author name and contact Signed-off-by: Shuang Yu --- .../langgraph-agentic-rag-multisource-retrieval/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md index f8434d0e..1f0bfea7 100644 --- a/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md +++ b/agents/community/langgraph-agentic-rag-multisource-retrieval/README.md @@ -45,13 +45,13 @@ A retrieval flow looks like: --- -Author: Sherry Yu (shuang.yu@ibm.com) +Authors: +- Sherry Yu (shuang.yu@ibm.com) +- Mateusz Świtała (mateusz.switala@ibm.com) Date: 16 April 2025 - - ## Directory structure and file descriptions The high level structure of the repository is as follows: