diff --git a/.gitmodules b/.gitmodules
index 1fb04cb7c..e69de29bb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "wren-engine"]
- path = wren-engine
- url = git@github.com:Canner/wren-engine.git
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
deleted file mode 100644
index 9eb5aecd6..000000000
--- a/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,53 +0,0 @@
-## Code of Conduct
-
-### Our Pledge
-
-We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
-
-We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
-
-### Our Standards
-
-Examples of behavior that contributes to a positive environment for our community include:
-
-- Demonstrating empathy and kindness toward other people
-- Being respectful of differing opinions, viewpoints, and experiences
-- Giving and gracefully accepting constructive feedback
-- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
-- Focusing on what is best not just for us as individuals, but for the overall community
-
-Examples of unacceptable behavior include:
-
-- The use of sexualized language or imagery, and sexual attention or advances of any kind
-- Trolling, insulting or derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others’ private information, such as a physical or email address, without their explicit permission
-- Other conduct which could reasonably be considered inappropriate in a professional setting
-
-### Enforcement Responsibilities
-
-Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
-
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
-
-### Scope
-
-This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
-
-### Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project team responsible for enforcement at [contact@getwren.ai](mailto:contact@getwren.ai). All complaints will be reviewed and investigated promptly and fairly.
-
-All project maintainers are obligated to respect the privacy and security of the reporter of any incident.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-### Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
-available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct/][version]
-
-[homepage]: http://contributor-covenant.org
-[version]: https://www.contributor-covenant.org/version/2/1
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index 69e6ce7de..000000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,164 +0,0 @@
-# Contributing Guidelines
-
-*Pull requests, bug reports, and all other forms of contribution are welcomed and highly encouraged!* :octocat:
-
-### Contents
-
-- [Code of Conduct](#book-code-of-conduct)
-- [Overview](#mag-overview)
-- [Contribution Guide of Different Services](#love_letter-contribution-guide-of-different-services)
-- [Creating a New Data Source Connector](#electric_plug-creating-a-new-data-source-connector)
-
-> **This guide serves to set clear expectations for everyone involved with the project so that we can improve it together while also creating a welcoming space for everyone to participate. Following these guidelines will help ensure a positive experience for contributors and maintainers.**
-
-## :book: Code of Conduct
-
-Please review our [Code of Conduct](https://github.com/Canner/WrenAI/blob/main/CODE_OF_CONDUCT.md). It is in effect at all times. We expect it to be honored by everyone who contributes to this project. Acting like an asshole will not be tolerated.
-
-
-## :rocket: Get Started
-1. Visit [How Wren AI works?](https://docs.getwren.ai/oss/overview/how_wrenai_works) to understand the architecture of Wren AI
-1. After you understand the architecture of Wren AI, understand the scope of the services you want to contribute to.
- Check each service's section under [Contribution Guide of Different Services](#love_letter-contribution-guide-of-different-services) to learn how to contribute to each service.
- 1. If you are dealing with UI-related tasks, such as adding a dark mode, you only need to contribute to the [Wren UI Service](#wren-ui-service).
- 2. If you are dealing with LLM-related tasks, such as enhancing the prompts used in the LLM pipelines, you only need to contribute to the [Wren AI Service](#wren-ai-service).
- 3. If you are working on data-source-related tasks, such as fixing a bug in SQL server connector, you will need to contribute to the [Wren Engine Service](#wren-engine-service).
-1. If you are not sure which service to contribute to, please reach out to us in [Discord](https://discord.gg/canner) or [GitHub Issues](https://github.com/Canner/WrenAI/issues).
-1. It's possible that you need to contribute to multiple services. For example, if you are adding a new data source, you will need to contribute to the [Wren UI Service](#wren-ui-service) and [Wren Engine Service](#wren-engine-service). Follow [Guide for Contributing to Multiple Services](#guide-for-contributing-to-multiple-services) to learn how to contribute to multiple services.
-
-## :love_letter: Contribution Guide of Different Services
-
-### Wren AI Service
-
-Wren AI Service is responsible for LLM-related tasks like converting natural language questions into SQL queries and providing step-by-step SQL breakdowns.
-
-To contribute to Wren AI Service, please refer to the [Wren AI Service Contributing Guide](https://github.com/Canner/WrenAI/blob/main/wren-ai-service/CONTRIBUTING.md)
-
-
-### Wren UI Service
-
-Wren UI is the client service of WrenAI. It is built with Next.js and TypeScript.
-To contribute to Wren UI, you can refer to the [WrenAI/wren-ui/README.md](https://github.com/Canner/WrenAI/blob/main/wren-ui/README.md) file for instructions on how to set up the development environment and run the development server.
-
-
-### Wren Engine Service
-Wren Engine is the backbone of the Wren AI project. The semantic engine for LLMs, bringing business context to AI agents.
-
-To contribute, please refer to [Wren Engine Contributing Guide](https://github.com/Canner/wren-engine/blob/main/ibis-server/docs/CONTRIBUTING.md)
-
-## Guide for Contributing to Multiple Services
-We rely on docker-compose to start all services. If you are contributing to multiple services, you could just comment out the services you'd like to start from the source code and change the `env` variables to point to the services you started by yourself.
-
-### Example: Contributing to the [Wren UI Service](#wren-ui-service) and [Wren Engine Service](#wren-engine-service)
-If you are contributing to both the [Wren UI Service](#wren-ui-service) and [Wren Engine Service](#wren-engine-service), you should comment out the `wren-engine` service in the `docker/docker-compose-dev.yml` file (note that the UI service is already excluded from `docker/docker-compose-dev.yml`). Then, adjust the environment variables in your `.env` file to point to the services you have started manually. This will ensure that your local development environment correctly interfaces with the services you are working on.
-
-1. Prepare your `.env` file: In the `WrenAI/docker` folder, use the `.env.example` file as a template. Copy this file to create a `.env.local` file.
- ```sh
- # assuming the current directory is wren-ui
- cd ../docker
- cp .env.example .env.local
- ```
-2. Modify your `.env.local` file: Fill in the `OPENAI_API_KEY` with your OpenAI API keys before starting.
-3. In the `WrenAI/docker` folder, copy `config.example.yaml` to `config.yaml` for AI service configuration. Also change `http://wren-ui:3000` to `http://host.docker.internal:3000` in `config.yaml`.
-4. Start the UI and engine services from the source code.
-5. Update the `env` variables in the `.env.local` file to point to the services you started manually.
-6. Start the other services using docker-compose:
- ```sh
- # current directory is WrenAI/docker
- docker-compose -f docker-compose-dev.yaml --env-file .env.example up
-
- # you can add the -d flag to run the services in the background
- docker-compose -f docker-compose-dev.yaml --env-file .env.example up -d
- # to stop the services, use
- docker-compose -f docker-compose-dev.yaml --env-file .env.example down
- ```
-7. Happy coding!
-
-## :electric_plug: Creating a New Data Source Connector
-
-To develop a new data source connector, you'll need to modify both the front-end and back-end of the Wren UI, in addition to the Wren Engine.
-
-Below is a brief overview of a data source connector:
-
-
-
-The UI is primarily responsible for storing database connection settings, providing an interface for users to input these settings, and submitting them to the Engine, which then connects to the database.
-
-The UI must be aware of the connection details it needs to retain, as specified by the Engine. Therefore, the implementation sequence would be as follows:
-
-
-- Engine:
- - Implement the new data source (you'll determine what connection information is needed and how it should be passed from the UI).
- - Implement the metadata API for the UI to access.
-- UI:
- - Back-End:
- - Safely store the connection information.
- - Provide the connection information to the Engine.
- - Front-End:
- - Prepare an icon for the data source.
- - Set up the form template for users to input the connection information.
- - Update the data source list.
-
-### Wren Engine
-
-- To implement a new data source, please refer to [How to Add a New Data Source](https://github.com/Canner/wren-engine/blob/main/ibis-server/docs/how-to-add-data-source.md).
-- After adding a new data source, you can proceed with implementing the metadata API for the UI.
-
- Here are some previous PRs that introduced new data sources:
- - [Add MSSQL data source](https://github.com/Canner/wren-engine/pull/631)
- - [Add MySQL data source](https://github.com/Canner/wren-engine/pull/618)
- - [Add ClickHouse data source](https://github.com/Canner/wren-engine/pull/648)
-
-### Wren UI Guide
-
-We'll describe what should be done in the UI for each new data source.
-
-If you prefer to learn by example, you can refer to this Trino [issue](https://github.com/Canner/WrenAI/issues/492) and [PR](https://github.com/Canner/WrenAI/pull/535).
-
-
-#### Backend
-1. Define the data source in `wren-ui/src/apollo/server/dataSource.ts`
- - define the `toIbisConnectionInfo` and `sensitiveProps` methods
-
-2. Modify the ibis adaptor in `wren-ui/src/apollo/server/adaptors/ibisAdaptor.ts`
- - define an ibis connection info type for the new data source
- - set up the `dataSourceUrlMap` for the new data source
-
-3. Modify the repository in `wren-ui/src/apollo/server/repositories/projectRepository.ts`
- - define the wren ui connection info type for the new data source
-
-4. Update the graphql schema in `wren-ui/src/apollo/server/schema.ts` so that the new data source can be used in the UI
- - add the new data source to the `DataSource` enum
-
-5. Update the type definition in `wren-ui/src/apollo/server/types/dataSource.ts`
- - add the new data source to the `DataSourceName` enum
-
-#### Frontend
-1. Prepare the data source's logo:
- - Image size should be `40 x 40` px
- - Preferably use SVG format
- - Ensure the logo is centered within a `30px` container for consistent formatting
-
- Example:
-
-
-
-2. Create the data source form template:
- - In `wren-ui/src/components/pages/setup/dataSources`, add a new file named `${dataSource}Properties.tsx`
- - Implement the data source form template in this file
-
-3. Set up the data source template:
- - Navigate to `wren-ui/src/utils/dataSourceType.ts`
- - Add new data source image, name, properties
- - Update the necessary files to include the new data source template settings
-
-4. Update the data source list:
- - Add the new data source to the `DATA_SOURCES` enum in `wren-ui/src/utils/enum/dataSources.ts`
- - Update relevant files in `wren-ui/src/components/pages/setup/` to include the new data source
- - Ensure `wren-ui/src/apollo/server/adaptors/ibisAdaptor.ts` handle the new data source
-
-5. Test the new connector:
- - Ensure the new data source appears in the UI
- - Verify that the form works correctly
- - Test the connection to the new data source
-
diff --git a/README.md b/README.md
deleted file mode 100644
index 96ced07d8..000000000
--- a/README.md
+++ /dev/null
@@ -1,160 +0,0 @@
-
-
-
-
-
-
-
- Wren AI - Open-Source GenBI Agent
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-> Ask your database anything in plain English. Wren AI generates accurate SQL, charts, and BI insights — backed by a semantic layer that keeps LLM outputs grounded and trustworthy.
-
-
-
-
-
-## 😍 Demos
-
-https://github.com/user-attachments/assets/f9c1cb34-5a95-4580-8890-ec9644da4160
-
-▶️ [Watch the full GenBI walkthrough](https://github.com/user-attachments/assets/90ad1d35-bb1e-490b-9676-b29863ff090b) — end-to-end from question to chart
-
-## 💡 Why a Semantic Layer?
-
-Feeding raw DDL to an LLM gets you SQL that looks right but means the wrong thing — "revenue" joins the wrong tables, "active user" uses the wrong filter. Wren AI's semantic layer (MDL) encodes your business definitions once, then every generated query is grounded in that shared understanding. The LLM doesn't guess what your metrics mean; the semantic layer tells it.
-
-## 🤖 Features
-
-| | What you get | Why it matters |
-|--------------------|--------------|----------------|
-| **Talk to Your Data** | Ask in any language → precise SQL & answers | Slash the SQL learning curve |
-| **GenBI Insights** | AI-written summaries, charts & reports | Decision-ready context in one click |
-| **Semantic Layer** | MDL models encode schema, metrics, joins | Keeps LLM outputs accurate & governed |
-| **Embed via API** | Generate queries & charts inside your apps ([API Docs](https://wrenai.readme.io/reference/cloud-getting-started)) | Build custom agents, SaaS features, chatbots ([Streamlit Live Demo](https://huggingface.co/spaces/getWrenAI/wrenai-cloud-api-demo)) |
-
-🤩 [Learn more about GenBI](https://getwren.ai/genbi?utm_source=github&utm_medium=content&utm_campaign=readme)
-
-## 🔌 Data Sources
-
-| Cloud Warehouses | Databases | Query Engines |
-|-----------------|-----------|---------------|
-| BigQuery | PostgreSQL | Trino |
-| Snowflake | MySQL | Athena (Trino) |
-| Redshift | Microsoft SQL Server | DuckDB |
-| Databricks | ClickHouse | |
-| | Oracle | |
-
-Don't see yours? [Vote for it](https://github.com/Canner/WrenAI/discussions/327) — community votes drive our connector roadmap.
-
-## 🧠 LLM Models
-
-Wren AI works with any LLM provider you're already using:
-
-| Cloud APIs | Platform Services | Self-hosted |
-|-----------|-------------------|-------------|
-| OpenAI | Azure OpenAI | Ollama |
-| Anthropic | Google AI Studio (Gemini) | |
-| DeepSeek | Vertex AI (Gemini + Anthropic) | |
-| Groq | AWS Bedrock | |
-| | Databricks | |
-
-> [!TIP]
-> For best results, use a frontier model (GPT-4o, Claude Sonnet, Gemini Pro). Wren AI works with smaller and local models too — accuracy scales with model capability. See [configuration examples](https://github.com/Canner/WrenAI/tree/main/wren-ai-service/docs/config_examples) for setup guides.
-
-## 🚀 Getting Started
-
-Three ways to get started — pick what fits:
-
-| Option | Best for | Link |
-|--------|----------|------|
-| **Self-hosted (Docker)** | Full control, local data | [Installation guide](http://docs.getwren.ai/oss/installation?utm_source=github&utm_medium=content&utm_campaign=readme) |
-| **Wren AI Cloud** | Try it without setup | [getwren.ai](https://getwren.ai/?utm_source=github&utm_medium=content&utm_campaign=readme) |
-
-Compare [OSS vs. Cloud plans](https://docs.getwren.ai/oss/overview/cloud_vs_self_host). Full documentation at [docs.getwren.ai](https://docs.getwren.ai/oss/overview/introduction?utm_source=github&utm_medium=content&utm_campaign=readme).
-
-
-
-
-
-## 🏗️ Architecture
-
-
-
-
-
-User questions flow from the Next.js UI → Apollo GraphQL → AI Service (RAG + LLM) → Wren Engine (semantic query execution) → your database. The semantic layer (MDL) sits at the center, making sure the LLM's SQL reflects your actual business definitions.
-
-👉 [Deep dive into the design](https://getwren.ai/post/how-we-design-our-semantic-engine-for-llms-the-backbone-of-the-semantic-layer-for-llm-architecture?utm_source=github&utm_medium=content&utm_campaign=readme)
-
-## 🧑💻 For Developers
-
-WrenAI is a full-stack AI system with interesting problems at every layer — semantic modeling, RAG retrieval, LLM-driven SQL generation, and query execution across heterogeneous data sources. Here's what the stack actually looks like under the hood:
-
-| Layer | What it does |
-|-------|-------------|
-| **wren-ui** | Next.js + Apollo GraphQL — semantic modeling UI and the BFF that wires everything together |
-| **wren-ai-service** | Python/FastAPI pipeline — intent classification, vector retrieval from Qdrant, LLM prompting, and SQL correction loops |
-| **[wren-engine](https://github.com/Canner/wren-engine)** | Rust + Apache DataFusion — the query execution core that resolves MDL semantics (metrics, joins, access controls) before SQL reaches the database |
-
-**[wren-engine](https://github.com/Canner/wren-engine)** is a separate open-source project and the part of the stack closest to the metal. It's where MDL definitions get translated into actual query plans across 15+ data sources. If you work with Rust, DataFusion, or database connectors, it's worth a look — the codebase is approachable and there are real unsolved problems around query planning, semantic resolution, and MCP (Model Context Protocol) agent integration.
-
-Some areas where contributions tend to have the most impact across both repos:
-
-- **Data source connectors** — wren-engine supports 15+ sources; new connectors are always useful
-- **MCP integration** — wren-engine exposes an MCP server; agent-native workflows are still early and evolving
-- **SQL generation quality** — prompt engineering, correction loop heuristics, and eval harnesses in wren-ai-service
-- **Semantic layer tooling** — MDL schema inference, validation, and developer ergonomics in wren-ui
-
-## 🛠️ Contribution
-
-1. Read [Contribution Guidelines](https://github.com/Canner/WrenAI/blob/main/CONTRIBUTING.md) for setup & PR guidelines.
-2. Open an issue for bugs, feature requests, or discussion.
-3. If Wren AI is useful to you, a ⭐ goes a long way — it helps more people find the project.
-
-## ⭐️ Community
-
-- Join 1.7k+ developers in our [Discord](https://discord.gg/5DvshJqG8Z) for real-time help and roadmap previews.
-- Visit [GitHub Issues](https://github.com/Canner/WrenAI/issues) for bugs and feature requests.
-- Explore our [public roadmap](https://wrenai.notion.site/) to see what's coming next.
-- [Subscribe to our blog](https://www.getwren.ai/blog/?utm_source=github&utm_medium=content&utm_campaign=readme) · [Follow us on LinkedIn](https://www.linkedin.com/company/wrenai)
-
-We follow a [Code of Conduct](./CODE_OF_CONDUCT.md) to keep the community welcoming for everyone.
-
-## 🎉 Our Contributors
-
-
-
-
-
- ⬆️ Back to Top
-
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index a9c0de266..000000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Security Policy
-## Reporting a Vulnerability
-
-If you believe you have found a security vulnerability in any Canner-owned repository, please report it to us through coordinated disclosure.
-
-**Please do not report security vulnerabilities through public GitHub issues, discussions, or pull requests.**
-
-Instead, please send an email to contact[@]cannerdata.com.
-
-Please include as much of the information listed below as you can to help us better understand and resolve the issue:
-
- * The type of issue (e.g., buffer overflow, SQL injection, or cross-site scripting)
- * Full paths of source file(s) related to the manifestation of the issue
- * The location of the affected source code (tag/branch/commit or direct URL)
- * Any special configuration required to reproduce the issue
- * Step-by-step instructions to reproduce the issue
- * Proof-of-concept or exploit code (if possible)
- * Impact of the issue, including how an attacker might exploit the issue
-
-This information will help us triage your report more quickly.
diff --git a/wren-mdl/mdl.schema.json b/core/wren-mdl/mdl.schema.json
similarity index 100%
rename from wren-mdl/mdl.schema.json
rename to core/wren-mdl/mdl.schema.json
diff --git a/deployment/README.md b/deployment/README.md
deleted file mode 100644
index 55936397e..000000000
--- a/deployment/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Various deployemnt starategies of the app
-
-- [x] [Docker](../docker/)
-- [x] [Kubernetes: Kustomizations](./kustomizations/)
\ No newline at end of file
diff --git a/deployment/kustomizations/.gitignore b/deployment/kustomizations/.gitignore
deleted file mode 100644
index 62b37177c..000000000
--- a/deployment/kustomizations/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.kustomized.yaml
-charts/*
\ No newline at end of file
diff --git a/deployment/kustomizations/README.md b/deployment/kustomizations/README.md
deleted file mode 100644
index 10fb7fa82..000000000
--- a/deployment/kustomizations/README.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# Deployment of Wren AI to Kubernetes with Kustomization
-1. Ensure you satisfy the dependencies required to deploy Wren AI.
-2. Adjust the values and manifests accordingly to fit your Kubernetes environment.
-3. Deploy Secrets separately.
-4. Deploy the inflated kustomized app.
-Note: Without authentication, once you publish this on the internet, anyone can access your app, see your data, and modify your settings!
-
-## Dependencies used in this kustomization:
-- nginx.ingress
-- external-dns
-- cert-manager
-- kubectl kustomize
-- helm (for minikube)
-
-## Steps to deploy:
-
-`Suggestion`: Before deploying, check out the manifests in the `deployment/kustomizations ` folder and modify them for your Kubernetes environment.
-The `deployment/kustomizations` folder contains a `kustomization.yaml` file that will inflate the manifests into a `deployment/kustomizations/wrenai.kustomized.yaml` file used to deploy the app to your Kubernetes cluster.
-
-```shell
-# Clone the repository with the kustomization
-git clone https://github.com/Canner/WrenAI.git
-cd WrenAI
-
-# Inflate the manifest with kustomization
-kubectl kustomize deployment/kustomizations --enable-helm > deployment/kustomizations/wrenai.kustomized.yaml
-
-# Create namespace
-kubectl create namespace wren
-
-# !!!!!!!!!!!!
-# MODIFY secret-wren_example.yaml manifest file FIRST
-# OPENAI_API_KEY is REQUIRED: without a valid key the wren-ai-service-deployment pod will not start
-# You must update PG_URL, otherwise wren-ui will not work
-#vi deployment/kustomizations/examples/secret-wren_example.yaml
-kubectl apply -f deployment/kustomizations/examples/secret-wren_example.yaml -n wren
-
-# Deploy the app:
-kubectl apply -f deployment/kustomizations/wrenai.kustomized.yaml
-
-kubectl get pods -n wren
-```
-
-### Notes on kustomization:
-- `deployment/kustomizations/kustomization.yaml` is the main file responsible for versions of other apps such as Qdrant and PostgreSQL, version of your Wren AI app. It also combines resourses from the manifest such as ConfigMaps, Deployments, and Services. And example Ingress, Certificates and Secrets.
-- `deployment/kustomizations/base` is the base folder that contains the core Wren AI manifests, its less likely you need to modify them, but check just in case
-- `deployment/kustomizations/examples` is a place with examples of manifests must take a look and adjust to your k8s environment and your needs.
-- `deployment/kustomizations/examples/secret-wren_example.yaml` is the file you would not normally include in the kustomization file as its not a best practice and especially not a good idea to include in your GitOps repo as it contains cleartext passwords. We recommend to deploy it separately. Thant's why its commented in the `kustomization.yaml` file.
-- `deployment/kustomizations/examples/wrenai-ingress-example.yaml` is an example of how to deploy Ingress. You can use this as a template for your own Ingress. It contains dependancy of extarnal-dns to add your dns name to your DNS records automatically, otherwise you'll need to add it manually. Also it assumes you are using nginx.ingress, it increases timeouts, disables the owasp and modsecurity that might be enabled globaly and prevent your UI from working properly. Comment the TLS section if you do not wish to use `https` encryption. Note: without authentication, enyone can acess your app, see your data and modify your settings!
-- `deployment/kustomizations/examples/certificate-wren_example.yaml` is an example of how to deploy certificates for your ingress for the Wren-UI. You can use this as a template for your own certificate. It contains dependancy of cert-manager to add your certificates automatically, otherwise you'll need to add it manually. The certificate will be used by your Ingress.
-- `deployment/kustomizations/examples/certificate-qdrant_example.yaml` is an example of how to deploy certificates for your ingress for Qdrant. This is included just in case and is not required, usually you would not be publishing your Vector Database publically in internet. That's why it's commented in the `kustomization.yaml` file. You can use this as a template for your own certificate. It contains dependancy of cert-manager to add your certificates automatically, otherwise you'll need to add it manually.
-- `deployment/kustomizations/patches` folder is empty, feel free to add your own patches & overlays there.
-
-#### Wren-UI Database
-Starting with wren-ui version 0.6.0 by default the postgres database is used for wren-ui in this kubernetes kustomization and will be installed in the same namespace as wren-ai.
-- `postgres`: Database that will be installed in the same namespace as wren-ai. You *must* update `PG_URL` in the Secret manifest `deployment/kustomizations/examples/secret-wren_example.yaml`.
-
-Example: `PG_URL: "postgres://postgres:postgres@wrenai-postgresql:5432/admin_ui"`
-- `postgres://` This is the protocol. It tells the system that you’re connecting to a PostgreSQL database.
-- `postgres:postgres` These are the username(first) and password(second) for the database respectively, separated by a colon. In this case, both the username and password are “postgres”.
-- `@wren-postgresql` This is the hostname of the database server. "wren-postgresql" means the database server is running in a Kubernetes cluster and it is named "wren-postgresql" in the *same* namespace. If you are using another namespace you must provide the full hostname, example: `wren-postgresql.wrenai.svc.cluster.local`, "wrenai" is the namespace name, "svc.cluster.local" is the default domain name for Kubernetes services no need to change it.
-- `:5432` This is the port number. PostgreSQL servers listen on port 5432 by default.
-- `/admin_ui` This is the name of the database you’re connecting to. In this case, the database name is `admin_ui`. It can be found in the helm values file in the auth.database parameter `deployment/kustomizations/helm-values_postgresql_15.yaml`
-
-# Minikube
-Prepare your k8s environment. Then use the `Steps to deploy` section to deploy Wren AI app into your k8s.
-```shell
-minikube start
-minikube addons enable ingress
-minikube addons enable metallb
-minikube kubectl -- get nodes
-minikube kubectl -- get pods -A
-
-minikube update-context
-helm repo add bitnami https://charts.bitnami.com/bitnami
-helm repo update
-helm install external-dns bitnami/external-dns
-helm install \
- external-dns bitnami/external-dns \
- --namespace external-dns \
- --version 7.5.2 \
- --create-namespace \
- --set installCRDs=true
-kubectl get pods -n external-dns
-
-helm repo add jetstack https://charts.jetstack.io
-helm repo update
-helm install \
- cert-manager jetstack/cert-manager \
- --namespace cert-manager \
- --version v1.13.6 \
- --create-namespace \
- --set installCRDs=true
-kubectl get pods -n cert-manager
-
-##########
-# Use the `Steps to deploy` section to continue as you would on a production k8s cluster.
-```
-
-# GitOps Patches
-In the [patches](./patches) folder you can find usefull kustomization examples files if you wish to use existing official kustomization directly from this repo as a base kustomization layer and only customize some values. It can be usefull for you GitOps workflow and can be used in conjunction with FlexCD or ArgoCD.
diff --git a/deployment/kustomizations/base/cm.yaml b/deployment/kustomizations/base/cm.yaml
deleted file mode 100644
index 0bbe6d5e1..000000000
--- a/deployment/kustomizations/base/cm.yaml
+++ /dev/null
@@ -1,240 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: wren-config
-data:
- # Wren Engine Service Port
- WREN_ENGINE_PORT: "8080"
- # Wren AI Service Port
- WREN_AI_SERVICE_PORT: "5555"
-
- WREN_UI_ENDPOINT: http://wren-ui-svc:3000
-
- #Release version used by wren ui https://github.com/Canner/WrenAI/blob/main/docker/docker-compose.yaml#L85-L88
- WREN_PRODUCT_VERSION: "0.12.0"
- WREN_ENGINE_VERSION: "0.12.3"
- WREN_AI_SERVICE_VERSION: "0.12.1"
- WREN_UI_VERSION: "0.17.6"
-
- # Document store related
- QDRANT_HOST: "wren-qdrant"
-
- # Telemetry
- POSTHOG_HOST: "https://app.posthog.com"
- TELEMETRY_ENABLED: "false"
- # this is for telemetry to know the model, i think ai-service might be able to provide a endpoint to get the information
- GENERATION_MODEL: "gpt-4o-mini-2024-07-18"
-
- # service endpoints of AI service & engine service
- WREN_ENGINE_ENDPOINT: "http://wren-engine-svc:8080"
- WREN_AI_ENDPOINT: "http://wren-ai-service-svc:5555"
- #WREN_AI_ENDPOINT: "http://wren-ai-service-svc.ai-system.svc.cluster.local:5555"
-
- # "pg" for postgres as UI application database
- WREN_UI_DB_TYPE: pg
-
- #For bootstrap
- WREN_ENGINE_DATA_PATH: "/app/data"
-
- ### if DB_TYPE = "postgres" you must provide PG_URL string in the *Secret* manifest file (deployment/kustomizations/examples/secret-wren_example.yaml) to connect to postgres
-
- #DEBUG, INFO
- LOGGING_LEVEL: INFO
-
- IBIS_SERVER_ENDPOINT: http://wren-ibis-server-svc:8000
----
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: wren-ai-service-config
-data:
- config.yaml: |
- type: llm
- provider: litellm_llm
- timeout: 120
- models:
- - alias: default
- model: gpt-4.1-nano-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-4.1-mini-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-4.1-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-5-nano-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
- - model: gpt-5-mini-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
- - model: gpt-5-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
- ---
- type: embedder
- provider: litellm_embedder
- models:
- - model: text-embedding-3-large
- alias: default
- timeout: 120
-
- ---
- type: engine
- provider: wren_ui
- endpoint: http://wren-ui-svc:3000
-
- ---
- type: engine
- provider: wren_ibis
- endpoint: http://wren-ibis-server-svc:8000
-
- ---
- type: document_store
- provider: qdrant
- location: http://wren-qdrant:6333
- embedding_model_dim: 3072
- timeout: 120
-
- ---
- type: pipeline
- pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
-
- ---
- settings:
- doc_endpoint: https://docs.getwren.ai
- is_oss: true
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/deployment/kustomizations/base/deploy-wren-ai-service.yaml b/deployment/kustomizations/base/deploy-wren-ai-service.yaml
deleted file mode 100644
index 41f91e822..000000000
--- a/deployment/kustomizations/base/deploy-wren-ai-service.yaml
+++ /dev/null
@@ -1,69 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: wren-ai-service-deployment
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: wren-ai-service
- template:
- metadata:
- labels:
- app: wren-ai-service
- spec:
- containers:
- - name: wren-ai-service
- image: ghcr.io/canner/wren-ai-service:latest
- volumeMounts:
- - name: config-volume
- mountPath: /app/data
- env:
- - name: WREN_AI_SERVICE_PORT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_AI_SERVICE_PORT
- - name: OPENAI_API_KEY
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: OPENAI_API_KEY
- - name: QDRANT_HOST
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: QDRANT_HOST
- - name: LOGGING_LEVEL
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: LOGGING_LEVEL
- - name: WREN_UI_ENDPOINT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_UI_ENDPOINT
- - name: PYTHONUNBUFFERED
- value: "1"
- - name: LANGFUSE_PUBLIC_KEY
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: LANGFUSE_PUBLIC_KEY
- - name: LANGFUSE_SECRET_KEY
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: LANGFUSE_SECRET_KEY
- - name: CONFIG_PATH
- value: /app/data/config.yaml
- ports:
- - containerPort: 5555
- volumes:
- - name: config-volume
- configMap:
- name: wren-ai-service-config
- items:
- - key: config.yaml
- path: config.yaml
diff --git a/deployment/kustomizations/base/deploy-wren-engine.yaml b/deployment/kustomizations/base/deploy-wren-engine.yaml
deleted file mode 100644
index b627c7233..000000000
--- a/deployment/kustomizations/base/deploy-wren-engine.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: wren-engine-deployment
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: wren-engine
- template:
- metadata:
- labels:
- app: wren-engine
- spec:
- volumes:
- - name: wren-data
- persistentVolumeClaim:
- claimName: wren-data-pvc
- initContainers:
- - name: bootstrap
- image: ghcr.io/canner/wren-bootstrap:0.1.4
- env:
- - name: DATA_PATH
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_ENGINE_DATA_PATH
- - name: PG_PASSWORD
- valueFrom:
- secretKeyRef:
- name: wrenai-postgresql
- key: postgres-password
- - name: PG_USERNAME
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: PG_USERNAME
- volumeMounts:
- - name: wren-data
- mountPath: /app/data
- command: ["/bin/sh", "/app/init.sh"]
- containers:
- - name: wren-engine
- image: ghcr.io/canner/wren-engine:0.4.4
- ports:
- - containerPort: 8080
- - containerPort: 7432
- volumeMounts:
- - name: wren-data
- mountPath: /usr/src/app/etc
\ No newline at end of file
diff --git a/deployment/kustomizations/base/deploy-wren-ibis-server.yaml b/deployment/kustomizations/base/deploy-wren-ibis-server.yaml
deleted file mode 100644
index 05bdbafbc..000000000
--- a/deployment/kustomizations/base/deploy-wren-ibis-server.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: wren-ibis-server
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: wren-ibis
- template:
- metadata:
- labels:
- app: wren-ibis
- spec:
- containers:
- - name: wren-ibis
- image: ghcr.io/canner/wren-engine-ibis:0.5.0
- env:
- - name: WREN_ENGINE_ENDPOINT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_ENGINE_ENDPOINT
- - name: LOGGING_LEVEL
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: LOGGING_LEVEL
- ports:
- - containerPort: 8000
diff --git a/deployment/kustomizations/base/deploy-wren-ui.yaml b/deployment/kustomizations/base/deploy-wren-ui.yaml
deleted file mode 100644
index 262da7882..000000000
--- a/deployment/kustomizations/base/deploy-wren-ui.yaml
+++ /dev/null
@@ -1,119 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: wren-ui-deployment
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: wren-ui
- template:
- metadata:
- labels:
- app: wren-ui
- spec:
- containers:
-
- - name: wren-ui
- image: ghcr.io/canner/wren-ui:0.5.6
- env:
- - name: DB_TYPE
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_UI_DB_TYPE
- - name: WREN_ENGINE_ENDPOINT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_ENGINE_ENDPOINT
- - name: WREN_AI_ENDPOINT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_AI_ENDPOINT
- - name: GENERATION_MODEL
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: GENERATION_MODEL
- - name: PG_URL
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: PG_URL
- # telemetry
- - name: WREN_ENGINE_PORT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_ENGINE_PORT
- - name: WREN_AI_SERVICE_VERSION
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_AI_SERVICE_VERSION
- - name: WREN_UI_VERSION
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_UI_VERSION
- - name: WREN_ENGINE_VERSION
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_ENGINE_VERSION
- - name: USER_UUID
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: USER_UUID
- - name: POSTHOG_API_KEY
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: POSTHOG_API_KEY
- - name: POSTHOG_HOST
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: POSTHOG_HOST
- - name: TELEMETRY_ENABLED
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: TELEMETRY_ENABLED
- # client side
- - name: NEXT_PUBLIC_USER_UUID
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: USER_UUID
- - name: NEXT_PUBLIC_POSTHOG_API_KEY
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: POSTHOG_API_KEY
- - name: NEXT_PUBLIC_POSTHOG_HOST
- valueFrom:
- secretKeyRef:
- name: wrenai-secrets
- key: POSTHOG_HOST
- - name: NEXT_PUBLIC_TELEMETRY_ENABLED
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: TELEMETRY_ENABLED
- # configs
- - name: WREN_PRODUCT_VERSION
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: WREN_PRODUCT_VERSION
- - name: IBIS_SERVER_ENDPOINT
- valueFrom:
- configMapKeyRef:
- name: wren-config
- key: IBIS_SERVER_ENDPOINT
- ports:
- - containerPort: 3000
diff --git a/deployment/kustomizations/base/pvc.yaml b/deployment/kustomizations/base/pvc.yaml
deleted file mode 100644
index 9158c3d67..000000000
--- a/deployment/kustomizations/base/pvc.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- name: wren-data-pvc
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 8Gi
-# storageClassName: vsphere-retain
diff --git a/deployment/kustomizations/base/svc.yaml b/deployment/kustomizations/base/svc.yaml
deleted file mode 100644
index a728afaff..000000000
--- a/deployment/kustomizations/base/svc.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-# Dependancy https://external-dns.io
-# You may want to add a DNS record for wren-ui.myhost.net host for your k8s Service instead of Ingress.
-# Note: without authentication, enyone can acess your app, see your data and modify your settings!
-# If this is the case, make sure to comment the ingress-wren_example.yaml manifest in the `kustomization.yaml` file to exclude it
-# And uncomment external-dns in the Service manifest here below:
-
-apiVersion: v1
-kind: Service
-metadata:
- name: wren-ui-svc
- #annotations:
- ### Dependancy external-dns
- #external-dns.alpha.kubernetes.io/filter: 'include'
- #external-dns.alpha.kubernetes.io/cloudflare-proxied: 'false'
- #external-dns.alpha.kubernetes.io/target: wren-ui.myhost.net
-spec:
- selector:
- app: wren-ui
- ports:
- - protocol: TCP
- port: 3000
- targetPort: 3000
- name: http-ui
----
-apiVersion: v1
-kind: Service
-metadata:
- name: wren-engine-svc
-spec:
- selector:
- app: wren-engine
- ports:
- - protocol: TCP
- port: 8080
- targetPort: 8080
- name: wren-engine
- - protocol: TCP
- port: 7432
- targetPort: 7432
- name: wren-engine-sql
----
-apiVersion: v1
-kind: Service
-metadata:
- name: wren-ai-service-svc
-spec:
- selector:
- app: wren-ai-service
- ports:
- - protocol: TCP
- port: 5555
- targetPort: 5555
- name: wren-ai-service
----
-apiVersion: v1
-kind: Service
-metadata:
- name: wren-ibis-server-svc
-spec:
- selector:
- app: wren-ibis
- ports:
- - protocol: TCP
- port: 8000
- targetPort: 8000
- name: wren-ibis
\ No newline at end of file
diff --git a/deployment/kustomizations/examples/.gitignore b/deployment/kustomizations/examples/.gitignore
deleted file mode 100644
index 5f4725008..000000000
--- a/deployment/kustomizations/examples/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-secret.yaml
\ No newline at end of file
diff --git a/deployment/kustomizations/examples/certificate-qdrant_example.yaml b/deployment/kustomizations/examples/certificate-qdrant_example.yaml
deleted file mode 100644
index e7d8c40e0..000000000
--- a/deployment/kustomizations/examples/certificate-qdrant_example.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-# To generate valid certificates into qdrant-ai.myhost.net-tls
-# Dependancy: install https://cert-manager.io
-apiVersion: cert-manager.io/v1
-kind: Certificate
-metadata:
- name: qdrant-ai.myhost.net
-spec:
- dnsNames:
- - qdrant-ai.myhost.net
- issuerRef:
- group: cert-manager.io
- kind: ClusterIssuer
- #### Replace with the name of your issuer
- name: myhost.net-prod
- secretName: qdrant-ai.myhost.net-tls
diff --git a/deployment/kustomizations/examples/certificate-wren_example.yaml b/deployment/kustomizations/examples/certificate-wren_example.yaml
deleted file mode 100644
index 2a99196b2..000000000
--- a/deployment/kustomizations/examples/certificate-wren_example.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# To generate valid certificates into wren-ui.myhost.net-tls
-# Dependancy: install https://cert-manager.io
-apiVersion: cert-manager.io/v1
-kind: Certificate
-metadata:
- name: wren-ui.myhost.net
-spec:
- dnsNames:
- - wren-ui.myhost.net
- issuerRef:
- group: cert-manager.io
- kind: ClusterIssuer
- ### Replace with the name of your issuer, otherwise the secret will be produce randoom name and the ingress will not work.
- name: myhost.net-prod
- ### Your ingress will be looking for this exact name:
- secretName: wren-ui.myhost.net-tls
diff --git a/deployment/kustomizations/examples/ingress-wren_example.yaml b/deployment/kustomizations/examples/ingress-wren_example.yaml
deleted file mode 100644
index 6163e0d31..000000000
--- a/deployment/kustomizations/examples/ingress-wren_example.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-# Dependancy https://external-dns.io
-# To add a DNS record for wren-ui.myhost.net host
-# Note: without authentication, enyone can acess your app, see your data and modify your settings!
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: wren-ui-ingress
- annotations:
- ### Dependancy external-dns
- #external-dns.alpha.kubernetes.io/filter: 'include'
- #external-dns.alpha.kubernetes.io/cloudflare-proxied: 'false'
- ##external-dns.alpha.kubernetes.io/cloudflare-proxied: 'true'
- external-dns.alpha.kubernetes.io/target: ingress1.myhost.net
- #external-dns.alpha.kubernetes.io/target: ingress2.myhost.net
-
- ### Dependancy nginx-ingress-controller
- nginx.ingress.kubernetes.io/disable-lua: 'true'
- nginx.ingress.kubernetes.io/enable-lua: 'false'
- nginx.ingress.kubernetes.io/enable-vts-status: 'false'
- nginx.ingress.kubernetes.io/enable-modsecurity: 'false'
- #nginx.ingress.kubernetes.io/modsecurity-snippet: |
- # SecRuleEngine Off
- nginx.ingress.kubernetes.io/enable-owasp-modsecurity-crs: 'false'
- nginx.ingress.kubernetes.io/proxy-connect-timeout: '360'
- nginx.ingress.kubernetes.io/proxy-read-timeout: '360'
- nginx.ingress.kubernetes.io/proxy-send-timeout: '360'
-
-spec:
- #instead you may use other ingressClassName such as AWS alb. If other than nginx ingress is used, don't forget to comment unsupported annotations above
- #"nginx" or "alb"
- ingressClassName: nginx
- rules:
- - host: wren-ui.myhost.net
- http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: wren-ui-svc
- port:
- number: 3000
-### Comment TLS section if you are not going to use https
- tls:
- - hosts:
- - wren-ui.myhost.net
- secretName: wren-ui.myhost.net-tls
diff --git a/deployment/kustomizations/examples/secret-wren_example.yaml b/deployment/kustomizations/examples/secret-wren_example.yaml
deleted file mode 100644
index 00711e8f2..000000000
--- a/deployment/kustomizations/examples/secret-wren_example.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
----
-apiVersion: v1
-kind: Secret
-metadata:
- name: wrenai-secrets
-type: Opaque
-data:
- # OPENAI_API_KEY is REQUIRED: without a valid key the wren-ai-service-deployment pod will not start
- OPENAI_API_KEY: UkVRVUlSRUQ6IHNrLXByb2otYWxsLWFjY2Vzcy1wbGFjZWhvbGRlci00LXdyZW4tYWktc2VydmljZS1kZXBsb3ltZW50
-
- # Azure openai env
- AZURE_CHAT_BASE: bi9h
- AZURE_CHAT_KEY: bi9h
- AZURE_CHAT_VERSION: bi9h
-
- AZURE_EMBED_BASE: bi9h
- AZURE_EMBED_KEY: bi9h
- AZURE_EMBED_VERSION: bi9h
-
- # Langfuse: for LLM tracing
- LANGFUSE_PUBLIC_KEY: xxxx
- LANGFUSE_SECRET_KEY: xxxx
-
- ### postgres:// This is the protocol. It tells the system that you’re connecting to a PostgreSQL database.
- ### postgres:postgres These are the username and password for the database, separated by a colon. In this case, both the username and password are “postgres”.
- ### @wren-postgresql This is the hostname of the database server. "wren-postgresql" means the database server is running in a Kubernetes cluster and it is named "wren-postgresql" in the *same* namespace. If you are using another namespace you must provide the full hostname, example: `wren-postgresql.wrenai.svc.cluster.local`, "wrenai" is the namespace name, "svc.cluster.local" is the default domain name for Kubernetes services no need to change it.
- ### :5432 This is the port number. PostgreSQL servers listen on port 5432 by default.
- ### /admin_ui This is the name of the database you’re connecting to. In this case, the database name is “admin_ui”. It can be found in the helm values file in the auth.database parameter (deployment/kustomizations/helm-values_postgresql_14.yaml)
- ### PG_URL: "postgres://postgres:postgres@wren-postgresql:5432/admin_ui"
- #Fix
- PG_URL: cG9zdGdyZXM6Ly9wb3N0Z3Jlczpwb3N0Z3Jlc0B3cmVuLXBvc3RncmVzcWw6NTQzMi9hZG1pbl91aQo=
- PG_USERNAME: cG9zdGdyZXM=
-
- POSTHOG_API_KEY: cGhjX2tleS1wbGFjZWhvbGRlcg==
- POSTHOG_HOST: aHR0cHM6Ly9hcHAucG9zdGhvZy5jb20=
- USER_UUID: MDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAw
----
-apiVersion: v1
-kind: Secret
-metadata:
- name: wrenai-postgresql
-data:
- postgres-password: cG9zdGdyZXM=
-type: Opaque
diff --git a/deployment/kustomizations/helm-values-qdrant_1.11.0.yaml b/deployment/kustomizations/helm-values-qdrant_1.11.0.yaml
deleted file mode 100644
index bf1ad9664..000000000
--- a/deployment/kustomizations/helm-values-qdrant_1.11.0.yaml
+++ /dev/null
@@ -1,234 +0,0 @@
-replicaCount: 1
-
-image:
- repository: docker.io/qdrant/qdrant
- pullPolicy: IfNotPresent
- tag: "v1.11.0"
- useUnprivilegedImage: false
-
-imagePullSecrets: []
-nameOverride: ""
-fullnameOverride: ""
-args: ["./config/initialize.sh"]
-env: {}
- # - name: QDRANT_ALLOW_RECOVERY_MODE
- # value: true
-
-# checks - Readiness and liveness checks can only be enabled for either http (REST) or grpc (multiple checks not supported)
-# grpc checks are only available from k8s 1.24+ so as of per default we check http
-service:
- type: ClusterIP
- additionalLabels: {}
- annotations: {}
- loadBalancerIP: ""
- ports:
- - name: http
- port: 6333
- targetPort: 6333
- protocol: TCP
- checksEnabled: true
- - name: grpc
- port: 6334
- targetPort: 6334
- protocol: TCP
- checksEnabled: false
- - name: p2p
- port: 6335
- targetPort: 6335
- protocol: TCP
- checksEnabled: false
-
-ingress:
- enabled: false
- ingressClassName: "nginx"
- additionalLabels: {}
- annotations:
- # Dependancy: https://kubernetes-sigs.github.io/external-dns
- #external-dns.alpha.kubernetes.io/filter: 'include'
- #external-dns.alpha.kubernetes.io/cloudflare-proxied: 'true'
- external-dns.alpha.kubernetes.io/target: ingress1.myhost.net
- hosts:
- - host: qdrant-ai.myhost.net
- paths:
- - path: /
- pathType: Prefix
- servicePort: 6333
- tls:
- - hosts:
- - qdrant-ai.myhost.net
- secretName: qdrant-ai.myhost.net-tls
-
-livenessProbe:
- enabled: false
- initialDelaySeconds: 5
- periodSeconds: 5
- timeoutSeconds: 1
- failureThreshold: 6
- successThreshold: 1
-
-readinessProbe:
- enabled: true
- initialDelaySeconds: 5
- periodSeconds: 5
- timeoutSeconds: 1
- failureThreshold: 6
- successThreshold: 1
-
-startupProbe:
- enabled: false
- initialDelaySeconds: 10
- periodSeconds: 5
- timeoutSeconds: 1
- failureThreshold: 30
- successThreshold: 1
-
-additionalLabels: {}
-podAnnotations: {}
-podLabels: {}
-
-resources: {}
- # limits:
- # cpu: 100m
- # memory: 128Mi
- # requests:
- # cpu: 100m
- # memory: 128Mi
-
-containerSecurityContext:
- runAsNonRoot: true
- runAsUser: 1000
- runAsGroup: 2000
- allowPrivilegeEscalation: false
- privileged: false
- readOnlyRootFilesystem: true
-
-podSecurityContext:
- fsGroup: 3000
- fsGroupChangePolicy: Always
-
-lifecycle:
- preStop:
- exec:
- # Sleeping before shutdown allows Qdrant to process requests that were
- # in-flight before the node is removed from load-balancing.
- # If using an external load balancer, you may need to increase this
- # duration to be greater than the LB's health check interval.
- command: ["sleep", "3"]
-
-# If true ensures that the pre-existing files on the storage and snapshot volume are owned by the container's
-# user and fsGroup
-updateVolumeFsOwnership: true
-
-nodeSelector: {}
-
-tolerations: []
-
-affinity: {}
-
-topologySpreadConstraints: []
-
-persistence:
- accessModes: ["ReadWriteOnce"]
- size: 20Gi
- annotations: {}
-# storageClassName: vsphere-retain
-
-# If you use snapshots or the snapshot shard transfer mechanism, we recommend
-# creating a separate volume of the same size as your main volume so that your
-# cluster won't crash if the snapshot is too big.
-snapshotPersistence:
- enabled: false
- accessModes: ["ReadWriteOnce"]
- size: 20Gi
- annotations: {}
- # You can change the storageClassName to ensure snapshots are saved to cold storage.
- # storageClassName: local-path
-
-snapshotRestoration:
- enabled: false
- # Set pvcName if you want to restore from a separately-created PVC. Only supported for single-node clusters unless the PVC is ReadWriteMany.
- # If you set snapshotPersistence.enabled and want to restore a snapshot from there, you can leave this blank to skip mounting an external volume.
- pvcName: snapshots-pvc
- # Must not conflict with /qdrant/snapshots or /qdrant/storage
- mountPath: /qdrant/snapshot-restoration
- snapshots:
- # - /qdrant/snapshot-restoration/test_collection/test_collection-2022-10-24-13-56-50.snapshot:test_collection
-
-# modification example for configuration to overwrite defaults
-config:
- cluster:
- enabled: true
- p2p:
- port: 6335
- consensus:
- tick_period_ms: 100
-
-sidecarContainers: []
-# sidecarContainers:
-# - name: my-sidecar
-# image: qdrant/my-sidecar-image
-# imagePullPolicy: Always
-# ports:
-# - name: my-port
-# containerPort: 5000
-# protocol: TCP
-# resources:
-# requests:
-# memory: 10Mi
-# cpu: 10m
-# limits:
-# memory: 100Mi
-# cpu: 100m
-
-metrics:
- serviceMonitor:
- enabled: false
- additionalLabels: {}
- scrapeInterval: 30s
- scrapeTimeout: 10s
- targetPort: http
- targetPath: "/metrics"
- ## MetricRelabelConfigs to apply to samples after scraping, but before ingestion.
- ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig
- ##
- metricRelabelings: []
- ## RelabelConfigs to apply to samples before scraping
- ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#relabelconfig
- ##
- relabelings: []
-
-serviceAccount:
- annotations: {}
-
-priorityClassName: ""
-
-# We disourage changing this setting. Using the "OrderedReady" policy in a
-# multi-node cluster will cause a deadlock where nodes refuse to become
-# "Ready" until all nodes are running.
-podManagementPolicy: Parallel
-
-podDisruptionBudget:
- enabled: false
- maxUnavailable: 1
- # do not enable if you are using not in 1.27
- unhealthyPodEvictionPolicy: ""
- # minAvailable: 1
-
-# api key for authentication at qdrant
-# false: no api key will be configured
-# true: an api key will be auto-generated
-# string: the given string will be set as an apikey
-apiKey: false
-# read-only api key for authentication at qdrant
-# false: no read-only api key will be configured
-# true: an read-only api key will be auto-generated
-# string: the given string will be set as a read-only apikey
-readOnlyApiKey: false
-
-additionalVolumes: []
-# - name: volumeName
-# emptyDir: {}
-
-additionalVolumeMounts: []
-# - name: volumeName
-# mountPath: "/mount/path"
diff --git a/deployment/kustomizations/helm-values_postgresql_15.yaml b/deployment/kustomizations/helm-values_postgresql_15.yaml
deleted file mode 100644
index c691fce5c..000000000
--- a/deployment/kustomizations/helm-values_postgresql_15.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-auth:
- secretKeys:
- adminPasswordKey: postgres-password
- existingSecret: wrenai-postgresql
-#creates admin_ui database
-global:
- postgresql:
- auth:
- database: admin_ui
\ No newline at end of file
diff --git a/deployment/kustomizations/kustomization.yaml b/deployment/kustomizations/kustomization.yaml
deleted file mode 100644
index 769f74afa..000000000
--- a/deployment/kustomizations/kustomization.yaml
+++ /dev/null
@@ -1,65 +0,0 @@
-##### Dependancies used in this kustomization:
-# nginx.ingress
-# external-dns
-# cert-manager
-# kubectl kustomize
-
-#test output like this:
-#kubectl kustomize deployment/kustomizations --enable-helm > deployment/kustomizations/wrenai.kustimized.yaml
-#kubectl create namespace wren
-#kubectl apply -f deployment/kustomizations/wrenai.kustimized.yaml
-apiVersion: kustomize.config.k8s.io/v1beta1
-kind: Kustomization
-
-# Namespace for all resources here and in the Helm charts
-namespace: wren
-helmCharts:
-
-### Uncomment if you are planing to use postgresql
- - name: postgresql
- repo: https://repo.vmware.com/bitnami-files
- version: 15.5.5
- releaseName: wren-postgresql
- valuesFile: helm-values_postgresql_15.yaml
- includeCRDs: true
- # the Same Namespace
- namespace: wren
-
- - name: qdrant
- repo: https://qdrant.github.io/qdrant-helm
- version: 1.11.0
- releaseName: wren-qdrant
- valuesFile: helm-values-qdrant_1.11.0.yaml
- includeCRDs: true
- # The Same Namespace
- namespace: wren
-
-
-images:
- # for the latest versions, please check here: https://github.com/Canner/WrenAI/blob/main/docker/.env.example#L23
- - name: ghcr.io/canner/wren-bootstrap
- newTag: 0.1.5 # WREN_BOOTSTRAP_VERSION
- - name: ghcr.io/canner/wren-engine
- newTag: 0.14.8 # WREN_ENGINE_VERSION
- - name: ghcr.io/canner/wren-ui
- newTag: 0.24.1 # WREN_UI_VERSION
- - name: ghcr.io/canner/wren-ai-service
- newTag: 0.19.7 # WREN_AI_SERVICE_VERSION
- - name: ghcr.io/canner/wren-engine-ibis
- newTag: 0.14.8 # IBIS_SERVER_VERSION
-
-resources:
- - base/cm.yaml
- - base/deploy-wren-ui.yaml
- - base/deploy-wren-engine.yaml
- - base/deploy-wren-ibis-server.yaml
- - base/deploy-wren-ai-service.yaml
- - base/pvc.yaml
- - base/svc.yaml
-### Modify these examples first and uncomment them:
- # - examples/ingress-wren_example.yaml
- # - examples/certificate-wren_example.yaml
-### Usually you do not need to generate a certificate for Qdrant
-# - examples/certificate-qdrant_example.yaml
-### Best practice is to create and deploy Secrets manually, not as part of kustomization or GitOps!
-# - examples/secret-wren_example.yaml
\ No newline at end of file
diff --git a/deployment/kustomizations/patches/README.md b/deployment/kustomizations/patches/README.md
deleted file mode 100644
index b20836c4c..000000000
--- a/deployment/kustomizations/patches/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Example of usefull Patches for Kustomization
-
-Patches from this folder allows to utilize the official unmodified deployment/kustomization dirrectly from the repo as a base layer for your kustomization. And then add patches to update some values. This is usefull for your GitOps and can be combined with tools such as ArgoCD and FluxCD.
-
-Patch ConfigMap, and Service if needed.
-Remove Certificate and Ingress if not needed.
\ No newline at end of file
diff --git a/deployment/kustomizations/patches/cm.yaml b/deployment/kustomizations/patches/cm.yaml
deleted file mode 100644
index 2c903f136..000000000
--- a/deployment/kustomizations/patches/cm.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-- op: replace
- path: /data
- value:
- # Wren Engine Service Port
- WREN_ENGINE_PORT: "8080"
- # Wren AI Service Port
- WREN_AI_SERVICE_PORT: "5555"
-
- #Release version used by wren ui https://github.com/Canner/WrenAI/blob/main/docker/docker-compose.yaml#L85-L88
- WREN_PRODUCT_VERSION: "0.12.0"
- #fix:
- WREN_ENGINE_VERSION: "0.12.3"
- WREN_AI_SERVICE_VERSION: "0.12.1"
- #fix:
- WREN_UI_VERSION: "0.17.6"
-
- # OpenAI
- GENERATION_MODEL: "gpt-4o-mini"
-
- # Telemetry
- POSTHOG_HOST: "https://app.posthog.com"
- TELEMETRY_ENABLED: "false"
-
- # service endpoints of AI service & engine service
- WREN_ENGINE_ENDPOINT: "http://wren-engine-svc:8080"
- #fix:
- WREN_AI_ENDPOINT: "http://wren-ai-service:5555"
-
- # "pg" for postgres as application database.
- #fix
- DB_TYPE: pg
-
- DATA_PATH: "/app/data"
-
- ### if DB_TYPE = "postgres" you must provide PG_URL string in the *Secret* manifest file (deployment/kustomizations/examples/secret-wren_example.yaml) to connect to postgres
diff --git a/deployment/kustomizations/patches/rm-certificate.yaml b/deployment/kustomizations/patches/rm-certificate.yaml
deleted file mode 100644
index 37f8f6932..000000000
--- a/deployment/kustomizations/patches/rm-certificate.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-$patch: delete
-apiVersion: v1
-kind: Certificate
-metadata:
- name: wren-ui.myhost.net
\ No newline at end of file
diff --git a/deployment/kustomizations/patches/rm-ingress.yaml b/deployment/kustomizations/patches/rm-ingress.yaml
deleted file mode 100644
index addeeff70..000000000
--- a/deployment/kustomizations/patches/rm-ingress.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-$patch: delete
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
- name: wren-ui-ingress
- annotations:
- external-dns.alpha.kubernetes.io/target: ingress1.myhost.net
\ No newline at end of file
diff --git a/deployment/kustomizations/patches/service.yaml b/deployment/kustomizations/patches/service.yaml
deleted file mode 100644
index f940acff0..000000000
--- a/deployment/kustomizations/patches/service.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-- op: replace
- path: /spec/ipFamilies
- value:
- - IPv6
- - IPv4
-
-- op: replace
- path: /spec/type
- value:
- LoadBalancer
-
-- op: replace
- path: /spec/ipFamilyPolicy
- value:
-# SingleStack
- PreferDualStack
\ No newline at end of file
diff --git a/docker/.env.example b/docker/.env.example
deleted file mode 100644
index 2bcf0723c..000000000
--- a/docker/.env.example
+++ /dev/null
@@ -1,53 +0,0 @@
-COMPOSE_PROJECT_NAME=wrenai
-PLATFORM=linux/amd64
-
-PROJECT_DIR=.
-
-# service port
-WREN_ENGINE_PORT=8080
-WREN_ENGINE_SQL_PORT=7432
-WREN_AI_SERVICE_PORT=5555
-WREN_UI_PORT=3000
-IBIS_SERVER_PORT=8000
-WREN_UI_ENDPOINT=http://wren-ui:${WREN_UI_PORT}
-
-# ai service settings
-QDRANT_HOST=qdrant
-SHOULD_FORCE_DEPLOY=1
-
-# vendor keys
-OPENAI_API_KEY=
-
-# version
-# CHANGE THIS TO THE LATEST VERSION
-WREN_PRODUCT_VERSION=0.29.1
-WREN_ENGINE_VERSION=0.22.0
-WREN_AI_SERVICE_VERSION=0.29.0
-IBIS_SERVER_VERSION=0.22.0
-WREN_UI_VERSION=0.32.2
-WREN_BOOTSTRAP_VERSION=0.1.5
-
-# user id (uuid v4)
-USER_UUID=
-
-# for other services
-POSTHOG_API_KEY=phc_nhF32aj4xHXOZb0oqr2cn4Oy9uiWzz6CCP4KZmRq9aE
-POSTHOG_HOST=https://app.posthog.com
-TELEMETRY_ENABLED=true
-# this is for telemetry to know the model, i think ai-service might be able to provide a endpoint to get the information.
-# AI model configurations should be set in config.yaml, not in .env. See README.md for more details.
-GENERATION_MODEL=gpt-4o-mini
-LANGFUSE_SECRET_KEY=
-LANGFUSE_PUBLIC_KEY=
-
-# the port exposes to the host
-# OPTIONAL: change the port if you have a conflict
-HOST_PORT=3000
-AI_SERVICE_FORWARD_PORT=5555
-
-# Wren UI
-EXPERIMENTAL_ENGINE_RUST_VERSION=false
-
-# Wren Engine
-# OPTIONAL: set if you want to use local storage for the Wren Engine
-LOCAL_STORAGE=.
diff --git a/docker/README.md b/docker/README.md
deleted file mode 100644
index d62873d97..000000000
--- a/docker/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-## Service
-
-- `wren-engine`: the engine service. check out example here: [wren-engine
- /example](https://github.com/Canner/wren-engine/tree/main/example)
-- `wren-ai-service`: the AI service.
-- `qdrant`: the vector store ai service is using.
-- `wren-ui`: the UI service.
-- `bootstrap`: put required files to volume for engine service.
-
-## Volume
-
-Shared data using `data` volume.
-
-Path structure as following:
-
-- `/mdl`
- - `*.json` (will put `sample.json` during bootstrap)
-- `accounts`
-- `config.properties`
-
-## Network
-
-- Check out [Network drivers overview](https://docs.docker.com/engine/network/drivers/) to learn more about `bridge` network driver.
-
-## How to start with OpenAI
-
-1. copy `.env.example` to `.env` and modify the OpenAI API key.
-2. copy `config.example.yaml` to `config.yaml` for AI service configuration.
-3. start all services: `docker-compose --env-file .env up -d`.
-4. stop all services: `docker-compose --env-file .env down`.
-
-### Optional
-
-- If your port 3000 is occupied, you can modify the `HOST_PORT` in `.env`.
-
-## How to start with custom LLM
-
-To start with a custom LLM, the process is similar to starting with OpenAI. The main difference is that you need to modify the `config.yaml` file
-that we created on the previous step. After modifying the file, you can restart the services by running `docker-compose --env-file .env up -d --force-recreate wren-ai-service`.
-
-For detailed information on how to modify the configuration for different LLM providers and models, please refer to the [AI Service Configuration](../wren-ai-service/docs/configuration.md).
-This guide provides comprehensive instructions on setting up various LLM providers, embedders, and other components of the AI service.
diff --git a/docker/bootstrap/Dockerfile b/docker/bootstrap/Dockerfile
deleted file mode 100644
index 330469832..000000000
--- a/docker/bootstrap/Dockerfile
+++ /dev/null
@@ -1,4 +0,0 @@
-FROM busybox
-
-WORKDIR /app
-COPY init.sh ./
\ No newline at end of file
diff --git a/docker/bootstrap/init.sh b/docker/bootstrap/init.sh
deleted file mode 100644
index 47bf9977c..000000000
--- a/docker/bootstrap/init.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-# declare a variable from the environment variable: DATA_PATH
-data_path=${DATA_PATH:-"./"}
-
-# touch a empty config.properties if not exists
-# put a content into config.properties if not exists
-if [ ! -f ${data_path}/config.properties ]; then
- echo "init config.properties"
- echo "node.environment=production" >${data_path}/config.properties
-fi
-
-# after the config.properties is created, check if config properties properly set
-# if not, then append default values to the config.properties
-# check if wren.experimental-enable-dynamic-fields is set, otherwise append it with true
-if ! grep -q "wren.experimental-enable-dynamic-fields" ${data_path}/config.properties; then
- echo "wren.experimental-enable-dynamic-fields is not set, set it to true"
- echo "wren.experimental-enable-dynamic-fields=true" >>${data_path}/config.properties
-fi
-
-# create a folder mdl if not exists
-if [ ! -d ${data_path}/mdl ]; then
- echo "create mdl folder"
- mkdir ${data_path}/mdl
-fi
-
-# put an emtpy sample.json if not exists
-if [ ! -f ${data_path}/mdl/sample.json ]; then
- echo "init mdl/sample.json"
- echo "{\"catalog\": \"test_catalog\", \"schema\": \"test_schema\", \"models\": []}" >${data_path}/mdl/sample.json
-fi
diff --git a/docker/config.example.yaml b/docker/config.example.yaml
deleted file mode 100644
index 2a22e788e..000000000
--- a/docker/config.example.yaml
+++ /dev/null
@@ -1,193 +0,0 @@
-type: llm
-provider: litellm_llm
-timeout: 120
-models:
- - alias: default
- model: gpt-4.1-nano-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-4.1-mini-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-4.1-2025-04-14
- context_window_size: 1000000
- kwargs:
- max_tokens: 4096
- n: 1
- seed: 0
- temperature: 0
- - model: gpt-5-nano-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
- - model: gpt-5-mini-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
- - model: gpt-5-2025-08-07
- context_window_size: 380000
- kwargs:
- max_completion_tokens: 4096
- n: 1
- seed: 0
- reasoning_effort: minimal
----
-type: embedder
-provider: litellm_embedder
-models:
- - model: text-embedding-3-large
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072
-timeout: 120
-recreate_index: true
-
----
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
-
----
-settings:
- doc_endpoint: https://docs.getwren.ai
- is_oss: true
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
\ No newline at end of file
diff --git a/docker/docker-compose-dev.yaml b/docker/docker-compose-dev.yaml
deleted file mode 100644
index 802bd4e1a..000000000
--- a/docker/docker-compose-dev.yaml
+++ /dev/null
@@ -1,95 +0,0 @@
-version: "3"
-
-volumes:
- data:
-
-networks:
- wren:
- driver: bridge
-
-services:
- bootstrap:
- image: ghcr.io/canner/wren-bootstrap:${WREN_BOOTSTRAP_VERSION}
- pull_policy: always
- platform: ${PLATFORM}
- environment:
- DATA_PATH: /app/data
- volumes:
- - data:/app/data
- command: /bin/sh /app/init.sh
-
- wren-engine:
- image: ghcr.io/canner/wren-engine:${WREN_ENGINE_VERSION}
- pull_policy: always
- platform: ${PLATFORM}
- expose:
- - ${WREN_ENGINE_SQL_PORT}
- ports:
- - ${WREN_ENGINE_PORT}:${WREN_ENGINE_PORT}
- volumes:
- - data:/usr/src/app/etc
- networks:
- - wren
- depends_on:
- - bootstrap
-
- wren-ai-service:
- image: ghcr.io/canner/wren-ai-service:${WREN_AI_SERVICE_VERSION}
- pull_policy: always
- platform: ${PLATFORM}
- ports:
- - ${AI_SERVICE_FORWARD_PORT}:${WREN_AI_SERVICE_PORT}
- environment:
- WREN_UI_ENDPOINT: http://host.docker.internal:${WREN_UI_PORT}
- # sometimes the console won't show print messages,
- # using PYTHONUNBUFFERED: 1 can fix this
- PYTHONUNBUFFERED: 1
- CONFIG_PATH: /app/config.yaml
- env_file:
- - ${PROJECT_DIR}/.env
- volumes:
- - ${PROJECT_DIR}/config.yaml:/app/config.yaml:ro
- - ${PROJECT_DIR}/data:/app/data:ro
- networks:
- - wren
- depends_on:
- - qdrant
-
- ibis-server:
- image: ghcr.io/canner/wren-engine-ibis:${IBIS_SERVER_VERSION}
- pull_policy: always
- platform: ${PLATFORM}
- expose:
- - 8000
- ports:
- - ${IBIS_SERVER_PORT}:8000
- environment:
- WREN_ENGINE_ENDPOINT: http://wren-engine:${WREN_ENGINE_PORT}
- LOG_LEVEL: DEBUG
- networks:
- - wren
-
- qdrant:
- image: qdrant/qdrant:v1.15.0
- pull_policy: always
- ports:
- - 6333:6333
- - 6334:6334
- networks:
- - wren
-
- # If you want to use postgres for testing purpose, uncomment the following block
- # postgres:
- # image: postgres:14-alpine
- # platform: ${PLATFORM}
- # ports:
- # - 9432:5432
- # volumes:
- # - data:/var/lib/postgresql/data
- # environment:
- # - POSTGRES_PASSWORD=secret
- # - POSTGRES_USER=test
- # - POSTGRES_DB=test
- # - PGDATA=/var/lib/postgresql/data/pgdata
- # networks:
- # - wren
diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml
deleted file mode 100644
index c7e125bdc..000000000
--- a/docker/docker-compose.yaml
+++ /dev/null
@@ -1,122 +0,0 @@
-version: "3"
-
-volumes:
- data:
-
-networks:
- wren:
- driver: bridge
-
-services:
- bootstrap:
- image: ghcr.io/canner/wren-bootstrap:${WREN_BOOTSTRAP_VERSION}
- restart: on-failure
- platform: ${PLATFORM}
- environment:
- DATA_PATH: /app/data
- volumes:
- - data:/app/data
- command: /bin/sh /app/init.sh
-
- wren-engine:
- image: ghcr.io/canner/wren-engine:${WREN_ENGINE_VERSION}
- restart: on-failure
- platform: ${PLATFORM}
- expose:
- - ${WREN_ENGINE_PORT}
- - ${WREN_ENGINE_SQL_PORT}
- volumes:
- - data:/usr/src/app/etc
- - ${PROJECT_DIR}/data:/usr/src/app/data
- networks:
- - wren
- depends_on:
- - bootstrap
-
- ibis-server:
- image: ghcr.io/canner/wren-engine-ibis:${IBIS_SERVER_VERSION}
- restart: on-failure
- platform: ${PLATFORM}
- expose:
- - ${IBIS_SERVER_PORT}
- environment:
- WREN_ENGINE_ENDPOINT: http://wren-engine:${WREN_ENGINE_PORT}
- volumes:
- - ${LOCAL_STORAGE:-.}:/usr/src/app/data
- networks:
- - wren
-
- wren-ai-service:
- image: ghcr.io/canner/wren-ai-service:${WREN_AI_SERVICE_VERSION}
- restart: on-failure
- platform: ${PLATFORM}
- expose:
- - ${WREN_AI_SERVICE_PORT}
- ports:
- - ${AI_SERVICE_FORWARD_PORT}:${WREN_AI_SERVICE_PORT}
- environment:
- # sometimes the console won't show print messages,
- # using PYTHONUNBUFFERED: 1 can fix this
- PYTHONUNBUFFERED: 1
- CONFIG_PATH: /app/config.yaml
- env_file:
- - ${PROJECT_DIR}/.env
- volumes:
- - ${PROJECT_DIR}/config.yaml:/app/config.yaml:ro
- - ${PROJECT_DIR}/data:/app/data:ro
- networks:
- - wren
- depends_on:
- - qdrant
-
- qdrant:
- image: qdrant/qdrant:v1.15.0
- restart: on-failure
- expose:
- - 6333
- - 6334
- volumes:
- - data:/qdrant/storage
- networks:
- - wren
-
- wren-ui:
- image: ghcr.io/canner/wren-ui:${WREN_UI_VERSION}
- restart: on-failure
- platform: ${PLATFORM}
- environment:
- DB_TYPE: sqlite
- # /app is the working directory in the container
- SQLITE_FILE: /app/data/db.sqlite3
- WREN_ENGINE_ENDPOINT: http://wren-engine:${WREN_ENGINE_PORT}
- WREN_AI_ENDPOINT: http://wren-ai-service:${WREN_AI_SERVICE_PORT}
- IBIS_SERVER_ENDPOINT: http://ibis-server:${IBIS_SERVER_PORT}
- # this is for telemetry to know the model, i think ai-service might be able to provide a endpoint to get the information
- GENERATION_MODEL: ${GENERATION_MODEL}
- # telemetry
- WREN_ENGINE_PORT: ${WREN_ENGINE_PORT}
- WREN_AI_SERVICE_VERSION: ${WREN_AI_SERVICE_VERSION}
- WREN_UI_VERSION: ${WREN_UI_VERSION}
- WREN_ENGINE_VERSION: ${WREN_ENGINE_VERSION}
- USER_UUID: ${USER_UUID}
- POSTHOG_API_KEY: ${POSTHOG_API_KEY}
- POSTHOG_HOST: ${POSTHOG_HOST}
- TELEMETRY_ENABLED: ${TELEMETRY_ENABLED}
- # client side
- NEXT_PUBLIC_USER_UUID: ${USER_UUID}
- NEXT_PUBLIC_POSTHOG_API_KEY: ${POSTHOG_API_KEY}
- NEXT_PUBLIC_POSTHOG_HOST: ${POSTHOG_HOST}
- NEXT_PUBLIC_TELEMETRY_ENABLED: ${TELEMETRY_ENABLED}
- EXPERIMENTAL_ENGINE_RUST_VERSION: ${EXPERIMENTAL_ENGINE_RUST_VERSION}
- # configs
- WREN_PRODUCT_VERSION: ${WREN_PRODUCT_VERSION}
- ports:
- # HOST_PORT is the port you want to expose to the host machine
- - ${HOST_PORT}:3000
- volumes:
- - data:/app/data
- networks:
- - wren
- depends_on:
- - wren-ai-service
- - wren-engine
diff --git a/misc/AI-generated-understanding_recommend_questions.png b/misc/AI-generated-understanding_recommend_questions.png
deleted file mode 100644
index efb346670..000000000
Binary files a/misc/AI-generated-understanding_recommend_questions.png and /dev/null differ
diff --git a/misc/API_doc.png b/misc/API_doc.png
deleted file mode 100644
index b8c9bed79..000000000
Binary files a/misc/API_doc.png and /dev/null differ
diff --git a/misc/data_source.png b/misc/data_source.png
deleted file mode 100644
index c0d6b6cb4..000000000
Binary files a/misc/data_source.png and /dev/null differ
diff --git a/misc/how_wrenai_works.png b/misc/how_wrenai_works.png
deleted file mode 100644
index 172aad541..000000000
Binary files a/misc/how_wrenai_works.png and /dev/null differ
diff --git a/misc/logo_template.jpg b/misc/logo_template.jpg
deleted file mode 100644
index 10b95f868..000000000
Binary files a/misc/logo_template.jpg and /dev/null differ
diff --git a/misc/preview_ask.png b/misc/preview_ask.png
deleted file mode 100644
index cff920f57..000000000
Binary files a/misc/preview_ask.png and /dev/null differ
diff --git a/misc/preview_model.png b/misc/preview_model.png
deleted file mode 100644
index cda6c52b5..000000000
Binary files a/misc/preview_model.png and /dev/null differ
diff --git a/misc/workflow.png b/misc/workflow.png
deleted file mode 100644
index 8f142ac3d..000000000
Binary files a/misc/workflow.png and /dev/null differ
diff --git a/misc/wren-context.png b/misc/wren-context.png
deleted file mode 100644
index 5fd4b7642..000000000
Binary files a/misc/wren-context.png and /dev/null differ
diff --git a/misc/wren-excel.png b/misc/wren-excel.png
deleted file mode 100644
index eb73527d4..000000000
Binary files a/misc/wren-excel.png and /dev/null differ
diff --git a/misc/wren-genbi.png b/misc/wren-genbi.png
deleted file mode 100644
index e1d280d7f..000000000
Binary files a/misc/wren-genbi.png and /dev/null differ
diff --git a/misc/wren-insight.png b/misc/wren-insight.png
deleted file mode 100644
index 795711494..000000000
Binary files a/misc/wren-insight.png and /dev/null differ
diff --git a/misc/wren-lang.png b/misc/wren-lang.png
deleted file mode 100644
index 7caaf1066..000000000
Binary files a/misc/wren-lang.png and /dev/null differ
diff --git a/misc/wren-modeling.png b/misc/wren-modeling.png
deleted file mode 100644
index 986a843a7..000000000
Binary files a/misc/wren-modeling.png and /dev/null differ
diff --git a/misc/wren-visual.png b/misc/wren-visual.png
deleted file mode 100644
index 2663d7543..000000000
Binary files a/misc/wren-visual.png and /dev/null differ
diff --git a/misc/wrenai_logo.png b/misc/wrenai_logo.png
deleted file mode 100644
index a1a066718..000000000
Binary files a/misc/wrenai_logo.png and /dev/null differ
diff --git a/misc/wrenai_logo_white.png b/misc/wrenai_logo_white.png
deleted file mode 100644
index 08a944ee1..000000000
Binary files a/misc/wrenai_logo_white.png and /dev/null differ
diff --git a/misc/wrenai_view.png b/misc/wrenai_view.png
deleted file mode 100644
index 132e491e6..000000000
Binary files a/misc/wrenai_view.png and /dev/null differ
diff --git a/misc/wrenai_vision.png b/misc/wrenai_vision.png
deleted file mode 100644
index e5af1f1af..000000000
Binary files a/misc/wrenai_vision.png and /dev/null differ
diff --git a/wren-ai-service/.dockerignore b/wren-ai-service/.dockerignore
deleted file mode 100644
index d8f8ab1f9..000000000
--- a/wren-ai-service/.dockerignore
+++ /dev/null
@@ -1,5 +0,0 @@
-*
-!src
-!entrypoint.sh
-!pyproject.toml
-src/eval
\ No newline at end of file
diff --git a/wren-ai-service/.pre-commit-config.yaml b/wren-ai-service/.pre-commit-config.yaml
deleted file mode 100644
index 9639e9b49..000000000
--- a/wren-ai-service/.pre-commit-config.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-repos:
-- repo: https://github.com/astral-sh/ruff-pre-commit
- # Ruff version.
- rev: v0.2.2
- hooks:
- # Run the linter.
- - id: ruff
- args: [ --fix ]
- # Run the formatter.
- - id: ruff-format
diff --git a/wren-ai-service/CONTRIBUTING.md b/wren-ai-service/CONTRIBUTING.md
deleted file mode 100644
index cc498cbae..000000000
--- a/wren-ai-service/CONTRIBUTING.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Welcome to Wren AI Service contributing guide
-
-Thank you for investing your time in contributing to our project! This document provides guidelines for contributing to the Wren AI service.
-
-## New contributor guide
-
-- To get an overview of the project, please read the [concepts](https://docs.getwren.ai/oss/concept/wren_ai_service).
-- To set up the project for local development, please read [Environment Setup](README.md#environment-setup) and [Start the service for development](README.md#start-the-service-for-development)
-- To understand the codebase more quickly, we've prepared [a codebase introduciton](docs/code_design.md) for you.
-
-## Getting started
-
-### Issues
-
-#### Create a new issue
-
-If you spot a problem, search if an issue already exists. If a related issue doesn't exist, you can open a new [issue](https://github.com/Canner/WrenAI/issues/new/choose).
-
-#### Solve an issue
-
-Scan through our [existing issues](https://github.com/Canner/WrenAI/issues?q=is%3Aopen+is%3Aissue+label%3Amodule%2Fai-service) to find one that interests you. As a general rule, we don't assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix.
-
-### Pull Request
-
-When you've finished with the changes, create a pull request, also known as a PR.
-- Fill the description so that we can review your PR.
-- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
-- Add the `module/ai-service` label to your PR.
-- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
- Once you submit your PR, a Canner team member will review your proposal. We may ask questions or request additional information.
-- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
-- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
-- Be sure to add one of the prefixes to the PR title, so that our CI could automatically capture the changelog of this PR.
- - `feat(wren-ai-service)`: for new features
- - `chore(wren-ai-service)`: for maintenance work
- - `fix(wren-ai-service)`: for bug fixes
-- If you run into any merge issues, checkout this [git tutorial](https://github.com/skills/resolve-merge-conflicts) to help you resolve merge conflicts and other issues.
-
-### Your PR is merged!
-
-Congratulations :tada::tada: The Canner team thanks you :sparkles:.
-
-Once your PR is merged, your contributions will be worked on the next release.
-
-Now that you are part of the Canner community.
-
-## How to add your preferred LLM, Embedder or Document Store
-
-- Please read [this documentation for further details](https://docs.getwren.ai/oss/ai_service/guide/custom_llm#adding-a-custom-llm-embedder-or-document-store-to-wren-ai).
diff --git a/wren-ai-service/Justfile b/wren-ai-service/Justfile
deleted file mode 100644
index 94fcb5a76..000000000
--- a/wren-ai-service/Justfile
+++ /dev/null
@@ -1,69 +0,0 @@
-GREEN := "\u{001b}[32m"
-YELLOW := "\u{001b}[33m"
-RESET := "\u{001b}[0m"
-
-## todo: consider to support --override flag to override existing files
-init dev='--dev':
- @if [ ! -f config.yaml ]; then \
- echo "{{GREEN}}config.yaml does not exist. Creating from example...{{RESET}}"; \
- cp tools/config/config.example.yaml config.yaml; \
- else \
- echo "{{YELLOW}}config.yaml already exists. Skipping creation.{{RESET}}"; \
- fi
-
- @if [ {{dev}} = "--dev" ] || [ {{dev}} != "--non-dev" ]; then \
- if [ ! -f .env.dev ]; then \
- echo "{{GREEN}}.env.dev does not exist. Creating from example...{{RESET}}"; \
- cp tools/config/.env.dev.example .env.dev; \
- else \
- echo "{{YELLOW}}.env.dev already exists. Skipping creation.{{RESET}}"; \
- fi \
- fi
-
-up: prepare-files
- docker compose -f ./tools/dev/docker-compose-dev.yaml --env-file ./tools/dev/.env up -d
-
-down:
- docker compose -f ./tools/dev/docker-compose-dev.yaml --env-file ./tools/dev/.env down
-
-start: force_update_config
- poetry run python -m src.__main__
-
-curate_eval_data:
- poetry run streamlit run eval/data_curation/app.py
-
-prep dataset='spider1.0':
- poetry run python -m eval.preparation --dataset {{dataset}}
-
-predict dataset pipeline='ask':
- poetry run python -u eval/prediction.py --file {{dataset}} --pipeline {{pipeline}}
-
-eval prediction_result semantics='--no-semantics':
- poetry run python -u eval/evaluation.py --file {{prediction_result}} {{semantics}}
-
-test test_args='': up && down
- poetry run pytest -s {{test_args}} --ignore tests/pytest/test_usecases.py
-
-test-usecases usecases='all' lang='en':
- poetry run python -m tests.pytest.test_usecases --usecases {{usecases}} --lang {{lang}}
-
-load-test:
- poetry run python -m tests.locust.locust_script
-
-prepare-files:
- # only remove files related to engine and ui
- rm -rf tools/dev/etc/duckdb tools/dev/etc/mdl tools/dev/etc/config.properties tools/dev/etc/db.sqlite3 tools/dev/etc/archived
- mkdir -p tools/dev/etc
- cp tools/dev/config.properties.example tools/dev/etc/config.properties
- mkdir -p tools/dev/etc/mdl
- echo "{\"catalog\": \"test_catalog\", \"schema\": \"test_schema\", \"models\": []}" \\
- > tools/dev/etc/mdl/sample.json
-
-force_update_config:
- poetry run python -m src.force_update_config
-
-run-sql mdl_path="" data_source="" sample_dataset="":
- poetry run python tools/run_sql.py --mdl-path "{{mdl_path}}" --data-source "{{data_source}}" --sample-dataset "{{sample_dataset}}"
-
-mdl-to-str mdl_path="":
- poetry run python tools/mdl_to_str.py -p {{mdl_path}}
diff --git a/wren-ai-service/README.md b/wren-ai-service/README.md
deleted file mode 100644
index b4dc9924e..000000000
--- a/wren-ai-service/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# AI Service of Wren AI
-
-## Concepts
-
-Please read the [documentation](https://docs.getwren.ai/oss/concept/wren_ai_service) here to understand the concepts of Wren AI Service.
-
-## Setup for Local Development
-
-### Prerequisites
-
-1. **Python**: Install Python 3.12.\*
-
- - Recommended: Use [`pyenv`](https://github.com/pyenv/pyenv?tab=readme-ov-file#installation) to manage Python versions
-
-2. **Poetry**: Install Poetry 1.8.3
-
- ```bash
- curl -sSL https://install.python-poetry.org | python3 - --version 1.8.3
- ```
-
-3. **Just**: Install [Just](https://github.com/casey/just?tab=readme-ov-file#packages) command runner (version 1.36 or higher)
-
-### Step-by-Step Setup
-
-1. **Install Dependencies**:
-
- ```bash
- poetry install
- ```
-
-2. **Generate Configuration Files**:
-
- ```bash
- just init
- ```
-
- This creates both `.env.dev` and `config.yaml`. Use `just init --non-dev` to generate only `config.yaml`.
-
- > For Windows, add the line `set shell:= ["bash", "-cu"]` at the start of the Justfile.
-
-4. **Configure Environment**:
-
- - Edit `.env.dev` to set environment variables
- - Modify `config.yaml` to configure components, pipelines, and other settings
- - Refer to [AI Service Configuration](./docs/configuration.md) for detailed setup instructions
-
-5. **Set Up Development Environment** (optional):
-
- - Install pre-commit hooks:
-
- ```bash
- poetry run pre-commit install
- ```
-
- - Run initial pre-commit checks:
-
- ```bash
- poetry run pre-commit run --all-files
- ```
-
-6. **Run Tests** (optional):
-
- ```bash
- just test
- ```
-
-### Starting the Service
-
-1. **Start Required Containers**:
-
- ```bash
- just up
- ```
-
-2. **Launch the AI Service**:
-
- ```bash
- just start
- ```
-
-3. **Access the Service**:
-
- - API Documentation: `http://WREN_AI_SERVICE_HOST:WREN_AI_SERVICE_PORT` (default: )
- - User Interface: `http://WREN_UI_HOST:WREN_UI_PORT` (default: )
-
-4. **Stop the Service**:
- When finished, stop the containers:
-
- ```bash
- just down
- ```
-
-This setup ensures a consistent development environment and helps maintain code quality through pre-commit hooks and tests. Follow these steps to get started with local development of the Wren AI Service.
-
-## Others
-
-### Pipeline Evaluation
-
-For a comprehensive understanding of how to evaluate the pipelines, please refer to the [evaluation framework](./eval/README.md). This document provides detailed guidelines on the evaluation process, including how to set up and run evaluations, interpret results, and utilize the evaluation metrics effectively. It is a valuable resource for ensuring that the evaluation is conducted accurately and that the results are meaningful.
-
-### Estimate the Speed of the Pipeline(may be outdated)
-
-- to run the load test
- - setup `DATASET_NAME` in `.env.dev`
- - adjust test config if needed
- - adjust user count in `tests/locust/config_users.json`
- - in wren-ai-service folder, run `just up` to start the docker containers
- - in wren-ai-service folder, run `just start` to start the ai service
- - run `just load-test`
- - check reports in /outputs/locust folder, there are 3 files with filename **locust*report*{test_timestamp}**:
- - .json: test report in json format, including info like llm provider, version
- - .html: test report in html format, showing tables and charts
- - .log: test log
-
-## Contributing
-
-Thank you for investing your time in contributing to our project! Please [read this for more information](CONTRIBUTING.md)!
diff --git a/wren-ai-service/docker/Dockerfile b/wren-ai-service/docker/Dockerfile
deleted file mode 100644
index 19388f3d8..000000000
--- a/wren-ai-service/docker/Dockerfile
+++ /dev/null
@@ -1,31 +0,0 @@
-# reference: https://medium.com/@albertazzir/blazing-fast-python-docker-builds-with-poetry-a78a66f5aed0
-FROM python:3.12.0-bookworm as builder
-
-RUN pip install poetry==1.8.3
-
-ENV POETRY_NO_INTERACTION=1 \
- POETRY_VIRTUALENVS_IN_PROJECT=1 \
- POETRY_VIRTUALENVS_CREATE=1 \
- POETRY_CACHE_DIR=/tmp/poetry_cache
-
-WORKDIR /app
-
-COPY pyproject.toml ./
-
-RUN poetry install --without dev,eval,test --no-root && rm -rf $POETRY_CACHE_DIR
-
-FROM python:3.12.0-slim-bookworm as runtime
-
-RUN apt-get update && apt install -y netcat-traditional
-
-ENV VIRTUAL_ENV=/app/.venv \
- PATH="/app/.venv/bin:$PATH"
-
-COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
-
-COPY src src
-COPY entrypoint.sh /app/entrypoint.sh
-COPY pyproject.toml pyproject.toml
-RUN chmod +x /app/entrypoint.sh
-
-ENTRYPOINT [ "/app/entrypoint.sh" ]
\ No newline at end of file
diff --git a/wren-ai-service/docs/code_design.md b/wren-ai-service/docs/code_design.md
deleted file mode 100644
index 7675d56ae..000000000
--- a/wren-ai-service/docs/code_design.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Introduction to the codebase of wren-ai-service
-
-## Table of Contents
-
-- [Purpose](#purpose)
-- [Environment Setup and Start wren-ai-service Locally](#environment-setup-and-start-wren-ai-service-locally)
-- [Codebase Introduction](#codebase-introduction)
- - [Entrypoint](#entrypoint)
- - [Globals](#globals)
- - [API endpoints](#api-endpoints)
- - [Services](#services)
- - [Pipelines](#pipelines)
- - [Providers](#providers)
- - [Others](#others)
-
-## Purpose
-
-This document aims to dive deep to the implementation details of wren-ai-service. We have two goals in mind while writing the document:
-1. You will be more knowledgeable about how wren-ai-service works under the hood.
-2. You will be more confident on what part of codebase is needed for adjustment if you would like to be Wren AI's contributor.
-
-## Environment Setup and Start wren-ai-service Locally
-
-If you haven't setup the environment or don't know how to run wren-ai-service locally, please refer to the [document](../README.md#setup-for-local-development) here first.
-
-## Codebase Introduction
-
-wren-ai-service is basically an AI service which provides REST api endpoints for access. There are 4 main concepts to wren-ai-service: `API endpoints`, `Services`, `Pipelines` and `Providers`.
-1. `API endpoints`: They are entry points for users to access several kinds of RAG(retrieval-augmented-generation) systems; you can also see API endpoints as encapsulation of Services. For example, when users need to ask a question in order to get SQL, they need to call `/ask` and there is AskService under the hood for background computation.
-2. `Services`: They are abstraction of business-logic concepts, such as AskService for users asking questions to get SQL results back, AskDetailsService for users to get SQL breakdown as several sub-steps in order to understand the logic behind the original SQL. Every service is composed of a series of pipelines.
-3. `Pipelines`: Basically RAG systems are actually implemented here. However, not all pipelines have complete indexing, retrieval and generation components; it depends on what's the purpose of the pipeline. Also, every pipeline contains some providers such as LLM provider, which represents an LLM.
-4. `Providers`: Now there are 4 kinds of providers:
- - llm: representing large language models, and now we support OpenAI, Azure OpenAI, OpenAI api-compatible and Ollama models
- - embedder: representing embedding models, and now we support OpenAI, Azure OpenAI, OpenAI api-compatible and Ollama models
- - document store: representing vector database, and now we use Qdrant
- - engine: representing data engine, which is responsible for validating generated SQL's syntax.
-
-### Entrypoint
-
-- The entry point of wren-ai-service is located at [`wren-ai-service/src/__main__.py`](../src/__main__.py)
-- The main point of the entry point is the `lifespan` method, which is FastAPI's feature for defining startup and shutdown logic.
-
-```python
-# https://fastapi.tiangolo.com/advanced/events/#lifespan
-@asynccontextmanager
-async def lifespan(app: FastAPI):
- # startup events
-
- pipe_components = generate_components()
- app.state.service_container = create_service_container(
- pipe_components,
- column_indexing_batch_size=(
- int(os.getenv("COLUMN_INDEXING_BATCH_SIZE"))
- if os.getenv("COLUMN_INDEXING_BATCH_SIZE")
- else 50
- ),
- table_retrieval_size=(
- int(os.getenv("TABLE_RETRIEVAL_SIZE"))
- if os.getenv("TABLE_RETRIEVAL_SIZE")
- else 10
- ),
- table_column_retrieval_size=(
- int(os.getenv("TABLE_COLUMN_RETRIEVAL_SIZE"))
- if os.getenv("TABLE_COLUMN_RETRIEVAL_SIZE")
- else 1000
- ),
- query_cache={
- # the maxsize is a necessary parameter to init cache, but we don't want to expose it to the user
- # so we set it to 1_000_000, which is a large number
- "maxsize": 1_000_000,
- "ttl": int(os.getenv("QUERY_CACHE_TTL") or 120),
- },
- )
- app.state.service_metadata = create_service_metadata(pipe_components)
- init_langfuse()
-
- yield
-
- # shutdown events
- langfuse_context.flush()
-```
-
-- For startup logic, we initialize pipeline components, service containers(which include all services), service metadata(which is some metadata logged for traces inside [Langfuse, an open-source LLM engineering platform](https://langfuse.com/)) and Langfuse.
-- For initializing pipeline components, we are in the progress of supporting multiple LLMs, namely users can choose which LLM is responsible for each pipeline.
- - You still need to have `.env.dev` locally, then you can prepare `config.yaml` and run `just start`.
-- For shutdown logic, we make sure all Langfuse events are transmitted successfully
-
-### Globals
-
-- The file is located at [`wren-ai-service/src/globals.py`](../src/globals.py)
-- You can understand the details of service containers and service metadata here
- - service containers(Other services are not supported in UI yet)
- - SemanticsPreparationService: this is responsible for indexing [MDL](https://docs.getwren.ai/oss/engine/concept/what_is_mdl) to Qdarnt
- - AskService: this is responsible for answering users' questions with SQLs, namely text-to-sql
- - AskDetailsService: this is responsible for SQL breakdown to several sub-steps
- - service metadata
- - We will record llm's and embedding model's metadata, wren-ai-service version, etc.
-
-### API endpoints
-
-- All business related API endpoints are located at [`wren-ai-service/src/web/v1/routers`](../src/web/v1/routers)
-- Since computation for each kind of API endpoint(ex. ask, etc.) takes several seconds, so we use FastAPI's `background_tasks`. For example, after the `ask` api is invoked, the response is immediately returned, then users need to conduct polling in order to get the latest task status; and once the status is `finished`, the result is returned correspondingly
-- Each kind of API endpoint corresponds to one kind of business related task, for example, AskService, AskDetailsService
-
-### Services
-
-- All services are located at [`wren-ai-service/src/web/v1/services`](../src/web/v1/services)
-
-### Pipelines
-
-- All pipelines are located at [`wren-ai-service/src/pipelines`](../src/pipelines)
-- Since all pipelines are actually RAG systems, so we classify the role of each pipeline as indexing, retrieval or generation
-- The abstract class is defined at [`wren-ai-service/src/core/pipeline.py`](../src/core/pipeline.py)
-
-### Providers
-
-- All providers are located at [`wren-ai-service/src/providers`](../src/providers)
-- The abstract classes for providers(LLM, embedding model and document store) are defined at [`wren-ai-service/src/core/provider.py`](../src/core/provider.py)
-- The abstract class for engine is defined at [`wren-ai-service/src/core/engine.py`](../src/core/engine.py)
diff --git a/wren-ai-service/docs/config_examples/README.md b/wren-ai-service/docs/config_examples/README.md
deleted file mode 100644
index 260ab9587..000000000
--- a/wren-ai-service/docs/config_examples/README.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# MUST READ!!!
-
-Since these config files are examples, so **please carefully read the file and comments inside**. Try to understand the purpose of each section and parameter, **don't simply copy and paste the content of these config files into your own config file. It will not work.** For more detailed information to the configurations, please [read this file](../configuration.md).
-
-We also definitely welcome your contribution to add config files for other LLM providers.
-
-## Qwen3 Think and No_Think Configuration
-
-The `config.qwen3.yaml` file provides an example configuration for using Qwen3 models with their unique thinking and non-thinking capabilities. Qwen3 models support two modes:
-
-### Thinking Mode
-- Use `/think` in your prompts to enable step-by-step reasoning
-- Optimized with `temperature=0.6`, `top_p=0.95`, `top_k=20`
-- Best for complex problems requiring detailed reasoning
-- Uses the `qwen3-thinking` alias in the pipeline configuration
-
-### Non-Thinking Mode
-- Use `/no_think` in your prompts for direct, fast responses
-- Optimized with `temperature=0.7`, `top_p=0.8`, `top_k=20`
-- Best for simple queries and general conversation
-- Uses the `qwen3-fast` alias in the pipeline configuration
-
-### Available Models
-- `qwen/qwen3-30b-a3b`: 30B parameter MoE model (3.3B activated)
-- `qwen/qwen3-32b`: 32B parameter dense model
-- `qwen/qwen3-8b`: 8B parameter dense model
-- `qwen/qwen3-14b`: 14B parameter dense model
-
-### Usage Examples
-```
-# Enable thinking for complex reasoning
-"Explain the mathematical proof for the Pythagorean theorem /think"
-
-# Use fast mode for simple queries
-"What is the capital of France? /no_think"
-```
-
-**Note**: You need to set `OPENROUTER_API_KEY` in your `~/.wrenai/.env` file to use OpenRouter as the provider for Qwen3 models.
diff --git a/wren-ai-service/docs/config_examples/config.anthropic.yaml b/wren-ai-service/docs/config_examples/config.anthropic.yaml
deleted file mode 100644
index 76e5d9652..000000000
--- a/wren-ai-service/docs/config_examples/config.anthropic.yaml
+++ /dev/null
@@ -1,169 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-timeout: 120
-models:
- # put ANTHROPIC_API_KEY= in ~/.wrenai/.env
- - api_base: https://api.anthropic.com
- model: anthropic/claude-3-7-sonnet-20250219
- alias: default
- timeout: 600
- kwargs:
- n: 1
- temperature: 0
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # anthropic embedding model is not supported yet, so we use openai embedding model as a workaround
- - model: text-embedding-3-large
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
\ No newline at end of file
diff --git a/wren-ai-service/docs/config_examples/config.azure.yaml b/wren-ai-service/docs/config_examples/config.azure.yaml
deleted file mode 100644
index 931939472..000000000
--- a/wren-ai-service/docs/config_examples/config.azure.yaml
+++ /dev/null
@@ -1,182 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-
-type: llm
-provider: litellm_llm
-models:
- # put AZURE_OPENAI_API_KEY= in ~/.wrenai/.env
- - model: azure/gpt-4 # Your Azure deployment name, put 'azure/' before deployment name
- alias: default
- api_base: https://endpoint.openai.azure.com # Replace with your custom Azure endpoint
- api_version: 2024-02-15-preview
- timeout: 120
- kwargs:
- temperature: 0
- n: 1
- seed: 0
- max_tokens: 4096
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # put AZURE_OPENAI_API_KEY= in ~/.wrenai/.env
- - model: azure/text-embedding-ada-002 # Your Azure deployment name, put 'azure/' before deployment name
- alias: default
- api_base: https://endpoint.openai.azure.com # Replace with your custom Azure endpoint
- api_version: 2023-05-15
- timeout: 300
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 1536 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant # Match document_store name
- llm: litellm_llm.default
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_preparation
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.bedrock.yaml b/wren-ai-service/docs/config_examples/config.bedrock.yaml
deleted file mode 100644
index a94474de6..000000000
--- a/wren-ai-service/docs/config_examples/config.bedrock.yaml
+++ /dev/null
@@ -1,185 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-timeout: 120
-models:
- - model: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0 # Inference profile ID, us. -> us-east-1, You can get it from "Cross-region inference" section
- api_base: https://bedrock-runtime..amazonaws.com
- alias: default
- kwargs:
- temperature: 0.1
- aws_region_name:
- aws_bedrock_runtime_endpoint: https://bedrock-runtime..amazonaws.com
-
- # to authenticate via iam role
- aws_role_name:
-
- ## other available configs
- # aws_access_key_id:
- # aws_secret_access_key:
- # aws_session_token:
- # aws_session_name:
- # aws_profile_name:
- # aws_web_identity_token:
- # aws_sts_endpoint:
-
----
-type: embedder
-provider: litellm_embedder
-models:
- - model: bedrock/amazon.titan-embed-text-v2:0
- api_base: https://bedrock-runtime..amazonaws.com
- timeout: 600
- alias: default
- kwargs:
- temperature: 0.1
- aws_region_name:
- aws_role_name:
- aws_bedrock_runtime_endpoint: https://bedrock-runtime..amazonaws.com
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 1024 # put your embedding model dimension here, 1024 for amazon-titan
-timeout: 120
-recreate_index: true
-
----
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.deepseek.yaml b/wren-ai-service/docs/config_examples/config.deepseek.yaml
deleted file mode 100644
index 3a00b30ad..000000000
--- a/wren-ai-service/docs/config_examples/config.deepseek.yaml
+++ /dev/null
@@ -1,192 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-
-type: llm
-provider: litellm_llm
-models:
- # put DEEPSEEK_API_KEY= in ~/.wrenai/.env
- - api_base: https://api.deepseek.com/v1
- model: deepseek/deepseek-reasoner
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- response_format:
- type: text
- - api_base: https://api.deepseek.com/v1
- model: deepseek/deepseek-chat
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- response_format:
- type: text
- - api_base: https://api.deepseek.com/v1
- model: deepseek/deepseek-coder
- alias: default
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- response_format:
- type: json_object
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # define OPENAI_API_KEY= in ~/.wrenai/.env if you are using openai embedding model
- # please refer to LiteLLM documentation for more details: https://docs.litellm.ai/docs/providers
- - model: text-embedding-3-large # put your embedding model name here, if it is not openai embedding model, should be /
- alias: default
- api_base: https://api.openai.com/v1 # change this according to your embedding model
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.deepseek/deepseek-chat
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.deepseek/deepseek-chat
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.deepseek/deepseek-reasoner
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.deepseek/deepseek-reasoner
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.google_ai_studio.yaml b/wren-ai-service/docs/config_examples/config.google_ai_studio.yaml
deleted file mode 100644
index 9d087accb..000000000
--- a/wren-ai-service/docs/config_examples/config.google_ai_studio.yaml
+++ /dev/null
@@ -1,178 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put GEMINI_API_KEY= in ~/.wrenai/.env
- - model: gemini/gemini-2.0-flash # gemini/
- alias: default
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- - model: gemini/gemini-2.0-flash # gemini/
- alias: gemini-llm-for-chart
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- response_format:
- type: json_object
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # put GEMINI_API_KEY= in ~/.wrenai/.env
- - model: gemini/text-embedding-004 # gemini/
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 768 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06 or . such as litellm_llm.gemini-llm-for-chart
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.gemini-llm-for-chart
- - name: chart_adjustment
- llm: litellm_llm.gemini-llm-for-chart
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.google_vertexai.yaml b/wren-ai-service/docs/config_examples/config.google_vertexai.yaml
deleted file mode 100644
index 0b29acb7e..000000000
--- a/wren-ai-service/docs/config_examples/config.google_vertexai.yaml
+++ /dev/null
@@ -1,186 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put VERTEXAI_LOCATION= in ~/.wrenai/.env
- # put VERTEXAI_PROJECT= in ~/.wrenai/.env
- # put GOOGLE_APPLICATION_CREDENTIALS=/app/data/ in ~/.wrenai.env
- - model: vertex_ai/gemini-2.5-flash # vertex_ai/
- alias: default
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- seed: 0
- max_tokens: 4096
- - model: vertex_ai/gemini-2.5-flash # vertex_ai/
- alias: gemini-llm-for-chart
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
- seed: 0
- max_tokens: 4096
- response_format:
- type: json_object
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # put VERTEXAI_LOCATION= in ~/.wrenai/.env
- # put VERTEXAI_PROJECT= in ~/.wrenai/.env
- # put GOOGLE_APPLICATION_CREDENTIALS=/app/data/ in ~/.wrenai.env
- - model: vertex_ai/text-embedding-004 # vertex_ai/
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 768 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06 or . such as litellm_llm.gemini-llm-for-chart
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.gemini-llm-for-chart
- - name: chart_adjustment
- llm: litellm_llm.gemini-llm-for-chart
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.grok.yaml b/wren-ai-service/docs/config_examples/config.grok.yaml
deleted file mode 100644
index b01de55b7..000000000
--- a/wren-ai-service/docs/config_examples/config.grok.yaml
+++ /dev/null
@@ -1,174 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put XAI_API_KEY= in ~/.wrenai/.env
- - api_base: https://api.x.ai/v1
- model: xai/grok-3-latest
- alias: default
- timeout: 120
- kwargs:
- temperature: 0
- max_tokens: 4096
- n: 1
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # define OPENAI_API_KEY= in ~/.wrenai/.env if you are using openai embedding model
- # please refer to LiteLLM documentation for more details: https://docs.litellm.ai/docs/providers
- - model: text-embedding-3-large # put your embedding model name here, if it is not openai embedding model, should be /
- alias: default
- api_base: https://api.openai.com/v1 # change this according to your embedding model
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.groq.yaml b/wren-ai-service/docs/config_examples/config.groq.yaml
deleted file mode 100644
index a07a577e9..000000000
--- a/wren-ai-service/docs/config_examples/config.groq.yaml
+++ /dev/null
@@ -1,173 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put GROQ_API_KEY= in ~/.wrenai/.env
- - api_base: https://api.groq.com/openai/v1
- model: groq/llama-3.3-70b-specdec # groq/
- alias: default
- timeout: 120
- kwargs:
- n: 1
- temperature: 0
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # define OPENAI_API_KEY= in ~/.wrenai/.env if you are using openai embedding model
- # please refer to LiteLLM documentation for more details: https://docs.litellm.ai/docs/providers
- - model: text-embedding-3-large # put your embedding model name here, if it is not openai embedding model, should be /
- alias: default
- api_base: https://api.openai.com/v1 # change this according to your embedding model
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.lm_studio.yaml b/wren-ai-service/docs/config_examples/config.lm_studio.yaml
deleted file mode 100644
index 131ac0438..000000000
--- a/wren-ai-service/docs/config_examples/config.lm_studio.yaml
+++ /dev/null
@@ -1,172 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put LM_STUDIO_API_KEY= in ~/.wrenai/.env
- - api_base: http://host.docker.internal:1234/v1
- model: openai/phi-4 # openai/
- alias: default
- timeout: 600
- kwargs:
- n: 1
- temperature: 0
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # put LM_STUDIO_API_KEY= in ~/.wrenai/.env
- - model: openai/text-embedding-nomic-embed-text-v1.5 # put your lm_studio embedder model name here, openai/
- alias: default
- api_base: http://host.docker.internal:1234/v1
- timeout: 600
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 768 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.ollama.yaml b/wren-ai-service/docs/config_examples/config.ollama.yaml
deleted file mode 100644
index 5f8e6c4ea..000000000
--- a/wren-ai-service/docs/config_examples/config.ollama.yaml
+++ /dev/null
@@ -1,172 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- - api_base: http://host.docker.internal:11434 # if you are using mac/windows, don't change this; if you are using linux, please search "Run Ollama in docker container" in this page: https://docs.getwren.ai/oss/ai_service/guide/custom_llm#running-wren-ai-with-your-custom-llm-embedder
- model: ollama_chat/phi4:14b # ollama_chat/
- alias: default
- timeout: 600
- kwargs:
- n: 1
- temperature: 0
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # at the moment, we are invoking ollama embedding model through ollama's openai compatible endpoint
- # since there is issue invoking ollama embedding model through ollama/ using litellm: https://github.com/BerriAI/litellm/issues/7572
- - model: openai/nomic-embed-text # put your ollama embedder model name here, openai/
- alias: default
- api_base: http://host.docker.internal:11434/v1 # if you are using mac/windows, don't change this; if you are using linux, please search "Run Ollama in docker container" in this page: https://docs.getwren.ai/oss/ai_service/guide/custom_llm#running-wren-ai-with-your-custom-llm-embedder
- timeout: 600
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 768 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.open_router.yaml b/wren-ai-service/docs/config_examples/config.open_router.yaml
deleted file mode 100644
index ecbcaa073..000000000
--- a/wren-ai-service/docs/config_examples/config.open_router.yaml
+++ /dev/null
@@ -1,170 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-timeout: 120
-models:
- # put OPENROUTER_API_KEY= in ~/.wrenai/.env
- - api_base: https://openrouter.ai/api/v1
- model: openrouter/anthropic/claude-3.7-sonnet
- alias: default
- timeout: 600
- kwargs:
- n: 1
- temperature: 0
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # put GEMINI_API_KEY= in ~/.wrenai/.env
- # openrouter embedding model is not supported yet, so you can use gemini embedding model as a workaround
- - model: gemini/text-embedding-004
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 768 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.default
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.default
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.default
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.default
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: false
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
\ No newline at end of file
diff --git a/wren-ai-service/docs/config_examples/config.qwen3.yaml b/wren-ai-service/docs/config_examples/config.qwen3.yaml
deleted file mode 100644
index 0ebaed162..000000000
--- a/wren-ai-service/docs/config_examples/config.qwen3.yaml
+++ /dev/null
@@ -1,212 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, 3 steps basically:
-# 1. you need to use your own llm and embedding models
-# 2. fill in embedding model dimension in the document_store section
-# 3. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 4. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # put OPENROUTER_API_KEY= in ~/.wrenai/.env
- # Qwen3 models support thinking and non-thinking modes
- # Use /think and /no_think in prompts to control reasoning behavior
- - api_base: https://openrouter.ai/api/v1
- model: openrouter/qwen/qwen3-30b-a3b
- alias: default
- timeout: 600
- kwargs:
- n: 1
- temperature: 0.6 # Recommended for thinking mode
- top_p: 0.95
- top_k: 20
- response_format:
- type: text
- - api_base: https://openrouter.ai/api/v1
- model: openrouter/qwen/qwen3-30b-a3b
- alias: qwen3-thinking
- timeout: 600
- kwargs:
- n: 1
- temperature: 0.6 # Optimized for thinking mode
- top_p: 0.95
- top_k: 20
- response_format:
- type: text
- - api_base: https://openrouter.ai/api/v1
- model: openrouter/qwen/qwen3-30b-a3b
- alias: qwen3-fast
- timeout: 600
- kwargs:
- n: 1
- temperature: 0.7 # Optimized for non-thinking mode
- top_p: 0.8
- top_k: 20
- response_format:
- type: text
- - api_base: https://openrouter.ai/api/v1
- model: openrouter/qwen/qwen3-32b
- alias: qwen3-32b
- timeout: 600
- kwargs:
- n: 1
- temperature: 0.6
- top_p: 0.95
- top_k: 20
- response_format:
- type: json_object
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # define OPENAI_API_KEY= in ~/.wrenai/.env if you are using openai embedding model
- # please refer to LiteLLM documentation for more details: https://docs.litellm.ai/docs/providers
- - model: text-embedding-3-large # put your embedding model name here, if it is not openai embedding model, should be /
- alias: default
- api_base: https://api.openai.com/v1 # change this according to your embedding model
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # put your embedding model dimension here
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.gpt-4o-2024-08-06
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.qwen3-fast
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.qwen3-fast
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.qwen3-thinking
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.qwen3-thinking
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/config_examples/config.zhipu.yaml b/wren-ai-service/docs/config_examples/config.zhipu.yaml
deleted file mode 100644
index 8d0db87d6..000000000
--- a/wren-ai-service/docs/config_examples/config.zhipu.yaml
+++ /dev/null
@@ -1,220 +0,0 @@
-# you should rename this file to config.yaml and put it in ~/.wrenai
-# please pay attention to the comments starting with # and adjust the config accordingly, steps:
-# 1. you need to get your Zhipu AI API key from https://open.bigmodel.cn/
-# 2. set your API key in environment variable
-# 3. fill in embedding model dimension in the document_store section
-# 4. you need to use the correct pipe definitions based on https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-# 5. you need to fill in correct llm and embedding models in the pipe definitions
-
-type: llm
-provider: litellm_llm
-models:
- # GLM-4.5 with thinking disabled - Method 1: Using allowed_openai_params
- - api_base: https://open.bigmodel.cn/api/paas/v4/
- model: openai/glm-4.5
- alias: default
- timeout: 900
- kwargs:
- n: 1
- temperature: 0.1
- top_p: 0.8
- extra_body:
- chat_template_kwargs:
- enable_thinking: false
- allowed_openai_params: ["extra_body"] # Force LiteLLM to allow extra_body
- # GLM-4.5 fast mode
- - api_base: https://open.bigmodel.cn/api/paas/v4/
- model: openai/glm-4.5
- alias: glm45-fast
- timeout: 900
- kwargs:
- n: 1
- temperature: 0.1
- top_p: 0.8
- extra_body:
- chat_template_kwargs:
- enable_thinking: false
- allowed_openai_params: ["extra_body"]
- # GLM-4.5 with thinking enabled for complex tasks
- - api_base: https://open.bigmodel.cn/api/paas/v4/
- model: openai/glm-4.5
- alias: glm45-thinking
- timeout: 1200 # Longer timeout for thinking mode
- kwargs:
- n: 1
- temperature: 0.3
- top_p: 0.9
- extra_body:
- chat_template_kwargs:
- enable_thinking: true
- allowed_openai_params: ["extra_body"]
- # GLM-4.5 for JSON responses with thinking disabled
- - api_base: https://open.bigmodel.cn/api/paas/v4/
- model: openai/glm-4.5
- alias: glm45-json
- timeout: 900
- kwargs:
- n: 1
- temperature: 0.05
- top_p: 0.7
- response_format:
- type: json_object
- extra_body:
- chat_template_kwargs:
- enable_thinking: false
- allowed_openai_params: ["extra_body"]
-
----
-type: embedder
-provider: litellm_embedder
-models:
- # define OPENAI_API_KEY= in ~/.wrenai/.env if you are using openai embedding model
- # GLM series doesn't have dedicated embedding models yet, so we use OpenAI embedding
- # please refer to LiteLLM documentation for more details: https://docs.litellm.ai/docs/providers
- - model: text-embedding-3-large
- alias: default
- timeout: 120
-
----
-type: engine
-provider: wren_ui
-endpoint: http://wren-ui:3000
-
----
-type: engine
-provider: wren_ibis
-endpoint: http://ibis-server:8000
-
----
-type: document_store
-provider: qdrant
-location: http://qdrant:6333
-embedding_model_dim: 3072 # text-embedding-3-large dimension
-timeout: 120
-recreate_index: true
-
----
-# please change the llm and embedder names to the ones you want to use
-# the format of llm and embedder should be . such as litellm_llm.glm45-fast
-# the pipes may be not the latest version, please refer to the latest version: https://raw.githubusercontent.com/canner/WrenAI//docker/config.example.yaml
-type: pipeline
-pipes:
- - name: db_schema_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: table_description_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: historical_question_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_correction
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: followup_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: sql_answer
- llm: litellm_llm.glm45-fast
- - name: semantics_description
- llm: litellm_llm.default
- - name: relationship_recommendation
- llm: litellm_llm.default
- engine: wren_ui
- - name: question_recommendation
- llm: litellm_llm.default
- - name: question_recommendation_db_schema_retrieval
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: question_recommendation_sql_generation
- llm: litellm_llm.default
- engine: wren_ui
- document_store: qdrant
- - name: chart_generation
- llm: litellm_llm.default
- - name: chart_adjustment
- llm: litellm_llm.default
- - name: intent_classification
- llm: litellm_llm.default
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: misleading_assistance
- llm: litellm_llm.default
- - name: data_assistance
- llm: litellm_llm.glm45-fast
- - name: sql_pairs_indexing
- document_store: qdrant
- embedder: litellm_embedder.default
- - name: sql_pairs_retrieval
- document_store: qdrant
- embedder: litellm_embedder.default
- llm: litellm_llm.default
- - name: preprocess_sql_data
- llm: litellm_llm.default
- - name: sql_executor
- engine: wren_ui
- - name: user_guide_assistance
- llm: litellm_llm.default
- - name: sql_question_generation
- llm: litellm_llm.default
- - name: sql_generation_reasoning
- llm: litellm_llm.glm45-thinking
- - name: followup_sql_generation_reasoning
- llm: litellm_llm.glm45-thinking
- - name: sql_regeneration
- llm: litellm_llm.default
- engine: wren_ui
- - name: instructions_indexing
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: instructions_retrieval
- embedder: litellm_embedder.default
- document_store: qdrant
- - name: sql_functions_retrieval
- engine: wren_ibis
- document_store: qdrant
- - name: project_meta_indexing
- document_store: qdrant
- - name: sql_tables_extraction
- llm: litellm_llm.default
- - name: sql_diagnosis
- llm: litellm_llm.default
- - name: sql_knowledge_retrieval
- engine: wren_ibis
- document_store: qdrant
----
-settings:
- engine_timeout: 30
- column_indexing_batch_size: 50
- table_retrieval_size: 10
- table_column_retrieval_size: 100
- allow_intent_classification: true
- allow_sql_generation_reasoning: true
- allow_sql_functions_retrieval: true
- enable_column_pruning: false
- max_sql_correction_retries: 3
- query_cache_maxsize: 1000
- query_cache_ttl: 3600
- langfuse_host: https://cloud.langfuse.com
- langfuse_enable: true
- logging_level: DEBUG
- development: true
- historical_question_retrieval_similarity_threshold: 0.9
- sql_pairs_similarity_threshold: 0.7
- sql_pairs_retrieval_max_size: 10
- instructions_similarity_threshold: 0.7
- instructions_top_k: 10
diff --git a/wren-ai-service/docs/configuration.md b/wren-ai-service/docs/configuration.md
deleted file mode 100644
index c88c39ce8..000000000
--- a/wren-ai-service/docs/configuration.md
+++ /dev/null
@@ -1,143 +0,0 @@
-# AI Service Configuration
-
-The AI service configuration is managed through a combination of environment variables and a configuration file, providing a flexible and secure approach to setting up the service.
-
-1. **Environment Variables**:
-
- - Used for configuring sensitive information such as vendor API keys
- - Specify the configuration file to use
- - Allow for partial settings to be configured directly, see [Settings Loading Mechanism](#settings-loading-mechanism) for more details
- - Provide a way to override settings in different environments
-
-2. **Configuration File**:
- - Used for detailed configuration of components, pipelines, and other service settings
- - Allows for more complex and structured configuration options
-
-This dual approach ensures that sensitive data can be kept secure (using environment variables) while allowing for more detailed and shareable configuration through the configuration file. It also provides flexibility in deployment across different environments.
-
-## Settings Loading Mechanism
-
-The AI service uses a hierarchical approach to load settings, ensuring flexibility across different environments and deployment scenarios. The settings are loaded in the following order of precedence:
-
-1. **Default Values**: These are defined as class attributes in the `Settings` class within [`config.py`](../src/config.py). They serve as the base configuration.
-
-2. **Environment Variables**: Using [pydantic-settings](https://fastapi.tiangolo.com/advanced/settings/#pydantic-settings), the service checks for environment variables that match the setting names. If found, these override the default values. For example, `WREN_AI_SERVICE_HOST` can override the default `host` value.
-
-3. **.env.dev File**: The service loads additional settings or overrides existing ones from a `.env.dev` file if present. This is particularly useful for development environments.
-
-4. **config.yaml File**: This file provides the highest priority configuration. It can override all previous settings and is used to configure components, pipelines, and other detailed settings. See [Configuration File](#configuration-file) for more details.
-
-This mechanism allows for easy configuration management across different environments, from development to production, while maintaining security for sensitive information like API keys.
-
-## Configuration File
-
-The configuration file (`config.yaml`) is structured into several sections, each defining different aspects of the AI service. Here's a breakdown of its main components:
-
-1. **LLM Configuration**:
-
- ```yaml
- type: llm
- provider:
- models:
- - model:
- kwargs: {}
- api_base:
- ```
-
- This component initializes the LLM provider at runtime. You can specify multiple models with different parameters. The `kwargs` field allows for model-specific configurations. For example:
-
- ```yaml
- type: llm
- provider: openai_llm
- models:
- - model: gpt-4
- kwargs:
- temperature: 0
- n: 1
- max_tokens: 4096
- response_format:
- type: "json_object"
- - model: gpt-4o-mini
- kwargs: {}
- api_base: https://api.openai.com/v1
- ```
-
- For detailed parameter options, refer to the implementation of the specific LLM provider.
-
-2. **Embedder Configuration**:
-
- ```yaml
- type: embedder
- provider:
- models:
- - model:
- dimension:
- api_base:
- timeout:
- ```
-
- This component configures the embedder, which converts text into numerical vectors. The `provider` specifies the embedder service (e.g., OpenAI, Ollama). You can define multiple `models` with their parameters. The `dimension` parameter indicates the size of the embedding vector.
-
-3. **Engine Configuration**:
-
- ```yaml
- type: engine
- provider:
- endpoint:
- ```
-
- This component configures the engine responsible for generating SQL queries. The `provider` specifies the engine service (e.g., Wren UI).
-
-4. **Document Store Configuration**:
-
- ```yaml
- type: document_store
- provider:
- ```
-
- This component configures the document store, which is responsible for storing and retrieving embeddings. The `provider` specifies the document store service (e.g., Qdrant).
-
-5. **Pipeline Configuration**:
-
- ```yaml
- type: pipeline
- pipes:
- - name:
- llm: .
- embedder: .
- engine:
- document_store:
- ```
-
- This component configures each pipeline, specifying different LLM, embedder, engine, and document store combinations. For LLM and embedder, use `.`. For engine and document store, use ``.
-
- Example:
-
- ```yaml
- type: pipeline
- pipes:
- - name: sql_generation
- llm: openai_llm.gpt-4o-mini
- engine: wren_ui
- ```
-
-6. **Settings**:
-
- ```yaml
- settings:
- host:
- port:
- column_indexing_batch_size:
- table_retrieval_size:
- table_column_retrieval_size:
- query_cache_maxsize:
- query_cache_ttl:
- langfuse_host:
- langfuse_enable:
- logging_level:
- development:
- ```
-
- This section defines various service settings including host, port, indexing and retrieval parameters, cache settings, Langfuse configuration, logging level, and development mode.
-
-This configuration file allows for detailed customization of the AI service components, pipelines, and overall behavior. It provides a centralized place to manage complex configurations while keeping sensitive information separate (managed through environment variables). See [Full Configuration File](../tools/config/config.full.yaml) for a complete example.
diff --git a/wren-ai-service/docs/imgs/shallow_trace_example.png b/wren-ai-service/docs/imgs/shallow_trace_example.png
deleted file mode 100644
index c228e99d4..000000000
Binary files a/wren-ai-service/docs/imgs/shallow_trace_example.png and /dev/null differ
diff --git a/wren-ai-service/entrypoint.sh b/wren-ai-service/entrypoint.sh
deleted file mode 100644
index c614a53c5..000000000
--- a/wren-ai-service/entrypoint.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-set -e
-
-INTERVAL=1
-TIMEOUT=60
-
-# Wait for qdrant to be responsive
-echo "Waiting for qdrant to start..."
-current=0
-
-while ! nc -z $QDRANT_HOST 6333; do
- sleep $INTERVAL
- current=$((current + INTERVAL))
- if [ $current -eq $TIMEOUT ]; then
- echo "Timeout: qdrant did not start within $TIMEOUT seconds"
- exit 1
- fi
-done
-echo "qdrant has started."
-
-# Start wren-ai-service in the background
-uvicorn src.__main__:app --host 0.0.0.0 --port $WREN_AI_SERVICE_PORT --loop uvloop --http httptools &
-
-if [[ -n "$SHOULD_FORCE_DEPLOY" ]]; then
-
- # Wait for the server to be responsive
- echo "Waiting for wren-ai-service to start..."
- current=0
-
- while ! nc -z localhost $WREN_AI_SERVICE_PORT; do
- sleep $INTERVAL
- current=$((current + INTERVAL))
- if [ $current -eq $TIMEOUT ]; then
- echo "Timeout: wren-ai-service did not start within $TIMEOUT seconds"
- exit 1
- fi
- done
- echo "wren-ai-service has started."
-
- # Wait for wren-ui to be responsive
- echo "Waiting for wren-ui to start..."
- current=0
-
- while ! nc -z wren-ui $WREN_UI_PORT && ! nc -z host.docker.internal $WREN_UI_PORT; do
- sleep $INTERVAL
- current=$((current + INTERVAL))
- if [ $current -eq $TIMEOUT ]; then
- echo "Timeout: wren-ui did not start within $TIMEOUT seconds"
- exit 1
- fi
- done
- echo "wren-ui has started."
-
- echo "Forcing deployment..."
- python -m src.force_deploy
-fi
-
-# Bring wren-ai-service to the foreground
-wait
diff --git a/wren-ai-service/eval/.gitignore b/wren-ai-service/eval/.gitignore
deleted file mode 100644
index 65cbde796..000000000
--- a/wren-ai-service/eval/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.env
-config.yaml
\ No newline at end of file
diff --git a/wren-ai-service/eval/README.md b/wren-ai-service/eval/README.md
deleted file mode 100644
index 92b653a74..000000000
--- a/wren-ai-service/eval/README.md
+++ /dev/null
@@ -1,160 +0,0 @@
-# Evaluation Framework
-
-This document describes the evaluation framework for the Wren AI service. The evaluation framework is designed to assess the performance of the Wren AI service based on the following components:
-
-## Requirements
-
-1. **Install Just**: Download and install [Just](https://github.com/casey/just?tab=readme-ov-file#packages) to run the evaluation framework commands.
-2. **Set up Langfuse**: Create an account on [Langfuse](https://cloud.langfuse.com) and obtain the API key and secret. Populate the `.env.dev` file with these credentials.
-3. **Start Development Services**: Run `just up` to initiate the necessary development services.
-4. **Configuration File**: Ensure you have a copy of `config.yaml` located in the `wren-ai-service/eval/` directory.
-
-## Dataset Curation
-
-The dataset curation process is used to prepare the evaluation dataset for the Wren AI service on evaluation purpose. You can follow the steps below to start the curation app:
-
-- copy `.env.example` to `.env` and fill in the environment variables
-- execute the command under the `wren-ai-service` folder: `just curate_eval_data`
-
-## Eval Dataset Preparation(If using Spider 1.0 dataset, or Bird dataset)
-
-```cli
-just prep
-```
-
-Currently, we support two datasets for evaluation:
-
-- `spider1.0`: The Spider dataset (default if no dataset specified)
-- `bird`: The Bird dataset
-
-The command performs two main steps:
-
-1. Downloads the specified dataset to:
-
- ```txt
- wren-ai-service/tools/dev/etc/
- ```
-
-2. Prepares and saves evaluation datasets to:
-
- ```txt
- wren-ai-service/eval/dataset
- ```
-
- The output files follow these naming conventions:
-
- - Spider dataset: `spider__eval_dataset.toml`
- - Bird dataset: `bird__eval_dataset.toml`
-
-Each evaluation dataset contains questions, SQL queries, and relevant context needed for testing the system's text-to-SQL capabilities.
-
-## Evaluation Dataset Schema
-
-- dataset_id(UUID)
-- date
-- mdl
-- eval dataset
-
-## Configure the datasource for prediction and evaluation
-
-Before starting the prediction and evaluation process, you need to configure the datasource correctly. This ensures that the system can access the necessary data for making predictions and evaluations.
-
-### For Spider or Bird Datasets
-
-For the Spider or Bird datasets, a built-in datasource is used. This means that the data is stored locally and accessed through a specific path. You need to specify the `eval_data_db_path` in the `config.yaml` file. This path tells the system where to find the database files.
-
-Here's an example of how to set this up in the `config.yaml` file:
-
-```yaml
-eval_data_db_path: "etc/bird/minidev/MINIDEV/dev_databases"
-```
-
-### Configuring BigQuery as a Datasource for Other custom MDLs
-
-When working with custom MDLs that utilize BigQuery as their datasource, it's crucial to properly configure your system to access the necessary datasets. This involves setting specific parameters in the `config.yaml` file or the `.env.dev` file. Both methods are effective, but using the `.env.dev` file is particularly beneficial for keeping sensitive credentials secure.
-
-#### Encoding the credentials
-
-You can use the following command to encode the credentials:
-
-```cli
-cat | base64
-```
-
-#### Configuration in `config.yaml`
-
-To enable access to your BigQuery dataset, add the following parameters to your `config.yaml` file. This configuration will guide the system in locating and authenticating with your BigQuery resources:
-
-```yaml
-bigquery_project_id: "your_project_id"
-bigquery_dataset_id: "your_dataset_id"
-bigquery_credentials: "your_credentials" # this is a base64 encoded string of the credentials
-```
-
-#### Configuration in `.env.dev`
-
-For the `.env.dev` file, you can use the following parameters:
-
-```env
-BIGQUERY_PROJECT_ID="your_project_id"
-BIGQUERY_DATASET_ID="your_dataset_id"
-BIGQUERY_CREDENTIALS="your_credentials" # this is a base64 encoded string of the credentials
-```
-
-## Prediction Process
-
-The prediction process is used to produce the results of the evaluation data using the Wren AI service. It will create traces and a session on Langfuse to make the results available to the user. You can use the following command to predict the evaluation dataset under the `eval/dataset` directory:
-
-```cli
-just predict
-```
-
-Also, sub-pipeline predictions are supported by specifying the pipeline name:
-
-```cli
-just predict
-```
-
-Currently, we support the following pipelines: 'ask', 'generation', and 'retrieval'. If no pipeline name is specified, the default is the 'ask' pipeline.
-
-## Evaluation Process
-
-The evaluation process is used to assess the prediction results of the Wren AI service. It compares the prediction results with the ground truth and calculates the evaluation metrics. This process will also add a trace in the same session on Langfuse to make the evaluation results available to the user. You can use the following command to evaluate the prediction results under the `outputs/predictions` directory:
-
-```cli
-just eval
-```
-
-Note: If you would like to enable semantics comparison between SQLs by LLM in order to improve the accuracy metric, please fill in Open AI API key in `.env` file in `wren-ai-service/eval` and add `--semantics` to the end of the command like following:
-
-```cli
-just eval --semantics
-```
-
-The evaluation results will be presented on Langfuse as follows:
-
-
-
-## Terms
-
-This section describes the terms used in the evaluation framework:
-
-- **input**: The user query used as input to the Wren AI service (e.g., "What is the total number of COVID-19 cases in the US?").
-- **actual_output**: The actual SQL query generated to retrieve the answer to the user query (e.g., "SELECT SUM(cases) FROM covid19 WHERE country='US'").
-- **expected_output**: The expected SQL query that should retrieve the answer to the user query (e.g., "SELECT SUM(cases) FROM covid19 WHERE country='US'").
-- **retrieval_context**: The relevant context that helps the LLM generate the SQL query (e.g., "covid19.country", "covid19.cases").
-- **context**: The relevant context that aligns with human expectations to generate the SQL query (e.g., "covid19.country", "covid19.cases").
-
-## Metrics
-
-This section describes the evaluation metrics used in the evaluation framework:
-
-- **Accuracy**: This metrics is defined as the proportion of the correct SQL output generated by the model compared to the expected SQL output. It checks if the generated SQL query produces the correct results.
-- **Answer Relevancy**: This metric helps determine how well your LLM generates relevant information based on the input it receives. It ensures the efficiency and accuracy of the model's output.
-- **Faithfulness**: This metric helps determine how well your LLM generates information that is factually correct and aligned with the retrieval context, minimizing hallucinations and contradictions.
-- **Contextual Relevancy**: This metric helps determine how well your retriever minimizes irrelevant information while maximizing the retrieval of relevant information. It ensures the efficiency and accuracy of the retrieval process.
-- **Contextual Recall**: This metric helps determine how well the embedding model identifies and retrieves relevant information based on the given context.
-- **Contextual Precision**: This metric helps determine how well the reranker places relevant nodes higher in the ranking, ensuring that users get the most pertinent results quickly.
-- **QuestionToReasoningJudge**: This metric helps determine how well the LLM generates reasoning that is aligned with the question.
-- **ReasoningToSqlJudge**: This metric helps determine how well the LLM generates SQL that is aligned with the reasoning.
-- **SqlSemanticsJudge**: This metric helps determine how well the LLM generates SQL that is semantically equivalent to the expected SQL.
diff --git a/wren-ai-service/eval/__init__.py b/wren-ai-service/eval/__init__.py
deleted file mode 100644
index b9850d58c..000000000
--- a/wren-ai-service/eval/__init__.py
+++ /dev/null
@@ -1,62 +0,0 @@
-from pathlib import Path
-
-from pydantic import Field, SecretStr
-
-from src.config import Settings
-
-SPIDER_DESTINATION_PATH = Path("./tools/dev/etc/spider1.0")
-BIRD_DESTINATION_PATH = Path("./tools/dev/etc/bird")
-WREN_ENGINE_API_URL = "http://localhost:8080"
-EVAL_DATASET_DESTINATION_PATH = Path("./eval/dataset")
-
-
-class EvalSettings(Settings):
- langfuse_project_id: str = ""
- batch_size: int = 4
- batch_interval: int = 1
- datasource: str = "bigquery"
- config_path: str = "eval/config.yaml"
- openai_api_key: SecretStr = Field(alias="OPENAI_API_KEY")
- allow_sql_samples: bool = True
- allow_instructions: bool = True
- allow_sql_functions: bool = True
- eval_data_db_path: str = ""
-
- # BigQuery
- bigquery_project_id: str = Field(default="")
- bigquery_dataset_id: str = Field(default="")
- bigquery_credentials: SecretStr = Field(default="")
-
- # Postgres
- postgres_host: str = Field(default="postgres")
- postgres_port: str = Field(default="5432")
- postgres_user: str = Field(default="postgres")
- postgres_password: SecretStr = Field(default="postgres")
- postgres_database: str = Field(default="test")
-
- @property
- def langfuse_url(self) -> str:
- if not self.langfuse_project_id:
- return ""
- return f"{self.langfuse_host.rstrip('/')}/project/{self.langfuse_project_id}"
-
- def get_openai_api_key(self) -> str:
- return self.openai_api_key.get_secret_value()
-
- @property
- def bigquery_info(self) -> dict:
- return {
- "project_id": self.bigquery_project_id,
- "dataset_id": self.bigquery_dataset_id,
- "credentials": self.bigquery_credentials.get_secret_value(),
- }
-
- @property
- def postgres_info(self) -> dict:
- return {
- "host": self.postgres_host,
- "port": self.postgres_port,
- "user": self.postgres_user,
- "password": self.postgres_password.get_secret_value(),
- "database": self.postgres_database,
- }
diff --git a/wren-ai-service/eval/add_samples_to_toml.py b/wren-ai-service/eval/add_samples_to_toml.py
deleted file mode 100644
index b52c12bbe..000000000
--- a/wren-ai-service/eval/add_samples_to_toml.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import argparse
-
-import tomlkit
-
-from eval.utils import (
- get_next_few_items_circular,
-)
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- parser.add_argument("--toml", type=str, help="The toml file name", required=True)
- args = parser.parse_args()
-
- if args.toml:
- # read toml
- with open(f"eval/dataset/{args.toml}", "r") as f:
- doc = tomlkit.parse(f.read())
-
- # get the list of question-sql pairs for generating sample values
- ground_truth_list = [
- {"question": element["question"], "sql": element["sql"]}
- for element in doc["eval_dataset"]
- ]
-
- # utilize utils.get_next_few_items_circular, put n samples in the eval dataset
- new_dataset = []
- for i, element in enumerate(doc["eval_dataset"]):
- samples = get_next_few_items_circular(ground_truth_list, i)
- element["samples"] = samples
- new_dataset.append(element)
-
- # write toml
- doc["eval_dataset"] = new_dataset
-
- with open(f"eval/dataset/added_samples_{args.toml}", "w") as f:
- f.write(tomlkit.dumps(doc, sort_keys=True))
diff --git a/wren-ai-service/eval/data_curation/__init__.py b/wren-ai-service/eval/data_curation/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/wren-ai-service/eval/data_curation/app.py b/wren-ai-service/eval/data_curation/app.py
deleted file mode 100644
index 615442abf..000000000
--- a/wren-ai-service/eval/data_curation/app.py
+++ /dev/null
@@ -1,494 +0,0 @@
-import asyncio
-import re
-import sys
-import uuid
-from datetime import datetime
-from pathlib import Path
-
-import orjson
-import pandas as pd
-import streamlit as st
-import tomlkit
-from openai import AsyncClient
-from streamlit_tags import st_tags
-
-sys.path.append(f"{Path().parent.resolve()}")
-from utils import (
- DATA_SOURCES,
- WREN_ENGINE_ENDPOINT,
- WREN_IBIS_ENDPOINT,
- get_contexts_from_sqls,
- get_data_from_wren_engine_with_sqls,
- get_question_sql_pairs,
- is_sql_valid,
- prettify_sql,
-)
-
-from eval import EvalSettings
-from eval.utils import (
- get_documents_given_contexts,
- get_eval_dataset_in_toml_string,
- get_openai_client,
- prepare_duckdb_init_sql,
- prepare_duckdb_session_sql,
-)
-
-st.set_page_config(layout="wide")
-st.title("WrenAI Data Curation App")
-
-
-LLM_OPTIONS = ["gpt-4o-mini", "gpt-4o"]
-
-settings = EvalSettings()
-llm_client = get_openai_client(api_key=settings.get_openai_api_key())
-
-# session states
-if "llm_model" not in st.session_state:
- st.session_state["llm_model"] = LLM_OPTIONS[0]
-if "deployment_id" not in st.session_state:
- st.session_state["deployment_id"] = str(uuid.uuid4())
-if "mdl_json" not in st.session_state:
- st.session_state["mdl_json"] = None
-if "custom_instructions_for_llm" not in st.session_state:
- st.session_state["custom_instructions_for_llm"] = ""
-if "llm_question_sql_pairs" not in st.session_state:
- st.session_state["llm_question_sql_pairs"] = []
-if "user_question_sql_pair" not in st.session_state:
- st.session_state["user_question_sql_pair"] = {}
-if "candidate_dataset" not in st.session_state:
- st.session_state["candidate_dataset"] = []
-if "data_source" not in st.session_state:
- st.session_state["data_source"] = None
-if "connection_info" not in st.session_state:
- st.session_state["connection_info"] = None
-
-
-# widget callbacks
-def on_change_upload_eval_dataset():
- doc = tomlkit.parse(st.session_state.uploaded_eval_file.getvalue().decode("utf-8"))
-
- assert (
- doc["mdl"] == st.session_state["mdl_json"]
- ), "The model in the uploaded dataset is different from the deployed model"
- st.session_state["candidate_dataset"] = doc["eval_dataset"]
-
-
-def on_change_custom_instructions_for_llm():
- st.session_state["custom_instructions_for_llm"] = st.session_state[
- "custom_instructions_text_area"
- ]
-
-
-def on_click_generate_question_sql_pairs(llm_client: AsyncClient):
- st.toast("Generating question-sql-pairs...")
- st.session_state["llm_question_sql_pairs"] = asyncio.run(
- get_question_sql_pairs(
- llm_client,
- st.session_state["llm_model"],
- st.session_state["mdl_json"],
- st.session_state["custom_instructions_for_llm"],
- st.session_state["data_source"],
- st.session_state["connection_info"],
- )
- )
-
-
-def on_click_setup_uploaded_file():
- uploaded_file = st.session_state.get("uploaded_mdl_file")
- if uploaded_file:
- match = re.match(
- r".+_(" + "|".join(DATA_SOURCES) + r")(_.+)?_mdl\.json$",
- uploaded_file.name,
- )
- if not match:
- st.error(
- f"the file name must be [xxx]_[datasource]_mdl.json, now we support these datasources: {DATA_SOURCES}"
- )
- st.stop()
-
- data_source = match.group(1)
- st.session_state["data_source"] = data_source
- st.session_state["mdl_json"] = orjson.loads(
- uploaded_file.getvalue().decode("utf-8")
- )
-
- if data_source == "bigquery":
- st.session_state["connection_info"] = settings.bigquery_info
- elif data_source == "duckdb":
- prepare_duckdb_session_sql(WREN_ENGINE_ENDPOINT)
- prepare_duckdb_init_sql(
- WREN_ENGINE_ENDPOINT,
- st.session_state["mdl_json"]["catalog"],
- "etc/spider1.0/database",
- )
- else:
- st.session_state["data_source"] = None
- st.session_state["mdl_json"] = None
- st.session_state["connection_info"] = None
-
-
-def on_change_llm_model():
- st.toast(f"Switching LLM model to {st.session_state['select_llm_model']}")
- st.session_state["llm_model"] = st.session_state["select_llm_model"]
-
-
-def on_change_sql(i: int, key: str):
- sql = st.session_state[key]
-
- valid, error = asyncio.run(
- is_sql_valid(
- sql,
- st.session_state["data_source"],
- st.session_state["mdl_json"],
- st.session_state["connection_info"],
- WREN_ENGINE_ENDPOINT
- if st.session_state["data_source"] == "duckdb"
- else WREN_IBIS_ENDPOINT,
- )
- )
- if valid:
- new_context = asyncio.run(
- get_contexts_from_sqls([sql], st.session_state["mdl_json"])
- )[0]
- document = get_documents_given_contexts(
- [new_context], st.session_state["mdl_json"]
- )
- if i != -1:
- st.session_state["llm_question_sql_pairs"][i]["sql"] = sql
- st.session_state["llm_question_sql_pairs"][i]["is_valid"] = valid
- st.session_state["llm_question_sql_pairs"][i]["error"] = error
- if valid:
- st.session_state["llm_question_sql_pairs"][i]["context"] = new_context
- st.session_state["llm_question_sql_pairs"][i]["document"] = document
- else:
- st.session_state["user_question_sql_pair"]["sql"] = sql
- st.session_state["user_question_sql_pair"]["is_valid"] = valid
- st.session_state["user_question_sql_pair"]["error"] = error
- if valid:
- st.session_state["user_question_sql_pair"]["context"] = new_context
- st.session_state["user_question_sql_pair"]["document"] = document
-
-
-def on_click_add_candidate_dataset(i: int, categories: list):
- if i != -1:
- dataset_to_add = {
- "categories": categories,
- "question": st.session_state["llm_question_sql_pairs"][i]["question"],
- "context": st.session_state["llm_question_sql_pairs"][i]["context"],
- "sql": st.session_state["llm_question_sql_pairs"][i]["sql"],
- "document": st.session_state["llm_question_sql_pairs"][i]["document"],
- }
- else:
- dataset_to_add = {
- "categories": categories,
- "question": st.session_state["user_question_sql_pair"]["question"],
- "context": st.session_state["user_question_sql_pair"]["context"],
- "sql": st.session_state["user_question_sql_pair"]["sql"],
- "document": st.session_state["user_question_sql_pair"]["document"],
- }
-
- # reset input for user question sql pair
- st.session_state["user_question_sql_pair"] = {}
- st.session_state["user_question"] = ""
- st.session_state["user_sql"] = ""
-
- should_add = True
- for dataset in st.session_state["candidate_dataset"]:
- if dataset == dataset_to_add:
- should_add = False
- break
-
- if should_add:
- st.session_state["candidate_dataset"].append(dataset_to_add)
-
-
-def on_change_user_question():
- if not st.session_state["user_question_sql_pair"]:
- st.session_state["user_question_sql_pair"] = {
- "question": st.session_state["user_question"],
- "context": [],
- "document": [],
- "sql": "",
- "is_valid": False,
- "error": "",
- }
- else:
- st.session_state["user_question_sql_pair"] = {
- **st.session_state["user_question_sql_pair"],
- "question": st.session_state["user_question"],
- }
-
-
-def on_click_remove_candidate_dataset_button(i: int):
- st.session_state["candidate_dataset"].pop(i)
-
-
-st.file_uploader(
- f"Upload an MDL json file, and the file name must be [xxx]_[datasource]_mdl.json, now we support these datasources: {DATA_SOURCES}",
- type="json",
- key="uploaded_mdl_file",
- on_change=on_click_setup_uploaded_file,
-)
-
-st.selectbox(
- label="Select which LLM model you want to use",
- options=LLM_OPTIONS,
- index=0,
- key="select_llm_model",
- on_change=on_change_llm_model,
-)
-
-tab_create_dataset, tab_modify_dataset = st.tabs(
- ["Create New Evaluation Dataset", "Modify Saved Evaluation Dataset"]
-)
-with tab_create_dataset:
- st.markdown(
- """
- ### Usage Guide
- 1. Upload an MDL json file first
- 2. Get question-sql-pairs given by LLM or you manually enter question and corresponding sql
- 3. Do validation on each group of question, context and SQL, and move it to the candidate dataset if you think it's valid
- 3. Save the candidate dataset by clicking the "Save as Evaluation Dataset" button.
- """
- )
-
-with tab_modify_dataset:
- st.markdown(
- """
- ### Usage Guide
- 1. Upload an MDL json file first
- 2. Upload the evaluation dataset(`.toml` file) you want to modify, and please make sure the model in the dataset is the same as the deployed model
- 3. Modify the evaluation dataset the same as you create a new one
- 4. Save the candidate dataset by clicking the "Save as Evaluation Dataset" button.
- """
- )
-
- st.warning(
- "WARNING: Uploading the evaluation dataset will overwrite the current candidate dataset"
- )
- st.file_uploader(
- "Upload Evaluation Dataset",
- type="toml",
- key="uploaded_eval_file",
- on_change=on_change_upload_eval_dataset,
- disabled=st.session_state["mdl_json"] is None,
- )
-
-if st.session_state["mdl_json"] is not None:
- col1, col2 = st.columns(2)
- with col1:
- st.markdown("### Question SQL Pairs")
- tab_generated_by_llm, tab_generated_by_user = st.tabs(
- ["Generated by LLM", "Generated by User"]
- )
-
- with tab_generated_by_llm:
- st.text_area(
- "Custom Instructions for generating question-sql-pairs (Optional)",
- key="custom_instructions_text_area",
- value=st.session_state["custom_instructions_for_llm"],
- placeholder="You can specify the custom instructions on how LLM should generate question-sql-pairs here, for example: what type of questions you want to generate.",
- on_change=on_change_custom_instructions_for_llm,
- )
-
- st.button(
- "Generate 10 question-sql-pairs",
- key="generate_question_sql_pairs",
- on_click=on_click_generate_question_sql_pairs,
- args=(llm_client,),
- )
-
- with st.container(border=True, height=550):
- for i, question_sql_pair in enumerate(
- st.session_state["llm_question_sql_pairs"]
- ):
- st.text_input(
- f"Question {i}",
- question_sql_pair["question"],
- disabled=True,
- key=f"question_{i}",
- )
- categories = st_tags(
- label=f"Categories {i}",
- text="Press enter to add more",
- value=[],
- key=f"categories_{i}",
- )
- st.multiselect(
- label=f"Context {i}",
- options=question_sql_pair["context"],
- default=question_sql_pair["context"],
- key=f"context_{i}",
- help="Contexts are automatically generated based on the SQL once you save the changes of the it(ctrl+enter or command+enter)",
- disabled=True,
- )
- st.text_area(
- f"SQL {i}",
- prettify_sql(question_sql_pair["sql"]),
- key=f"sql_{i}",
- height=250,
- on_change=on_change_sql,
- args=(i, f"sql_{i}"),
- )
- if st.session_state["llm_question_sql_pairs"][i]["is_valid"]:
- st.success("SQL is valid")
- st.dataframe(
- pd.DataFrame(
- question_sql_pair["data"]["data"],
- columns=question_sql_pair["data"]["columns"],
- )
- )
- else:
- st.error(
- f"SQL is invalid: {st.session_state['llm_question_sql_pairs'][i]['error']}"
- )
-
- st.button(
- "Move it to the candidate dataset",
- key=f"move_to_dataset_{i}",
- disabled=(
- not st.session_state["llm_question_sql_pairs"][i][
- "is_valid"
- ]
- or not st.session_state[f"context_{i}"]
- or not categories
- ),
- on_click=on_click_add_candidate_dataset,
- args=(
- i,
- categories,
- ),
- )
-
- st.markdown("---")
-
- with tab_generated_by_user:
- with st.container(border=True, height=550):
- st.text_input(
- "Question",
- disabled=False,
- key="user_question",
- on_change=on_change_user_question,
- )
- categories = st_tags(
- label="Categories",
- text="Press enter to add more",
- value=[],
- key="user_categories",
- )
- st.multiselect(
- label="Context",
- options=st.session_state.get("user_question_sql_pair", {}).get(
- "context", []
- ),
- default=st.session_state.get("user_question_sql_pair", {}).get(
- "context", []
- ),
- key="user_context",
- help="Contexts are automatically generated based on the SQL once you save the changes of the it(ctrl+enter or command+enter)",
- disabled=True,
- )
- st.text_area(
- "SQL",
- key="user_sql",
- height=250,
- on_change=on_change_sql,
- args=(-1, "user_sql"),
- )
-
- if st.session_state.get("user_question_sql_pair", {}).get(
- "is_valid", False
- ):
- st.success("SQL is valid")
- data = asyncio.run(
- get_data_from_wren_engine_with_sqls(
- [st.session_state["user_question_sql_pair"]["sql"]],
- st.session_state["data_source"],
- st.session_state["mdl_json"],
- st.session_state["connection_info"],
- WREN_ENGINE_ENDPOINT
- if st.session_state["data_source"] == "duckdb"
- else WREN_IBIS_ENDPOINT,
- )
- )[0]
- st.dataframe(
- pd.DataFrame(
- data["data"],
- columns=data["columns"],
- )
- )
- else:
- st.error(
- f"SQL is invalid: {st.session_state.get('user_question_sql_pair', {}).get('error', '')}"
- )
-
- st.button(
- "Move it to the candidate dataset",
- key="move_to_dataset",
- disabled=(
- not st.session_state.get("user_question_sql_pair", {}).get(
- "is_valid", False
- )
- or not st.session_state["user_context"]
- or not st.session_state["user_question"]
- or not categories
- ),
- on_click=on_click_add_candidate_dataset,
- args=(
- -1,
- categories,
- ),
- )
- with col2:
- st.markdown("### Candidate Dataset")
-
- with st.container(border=True, height=600):
- for i, dataset in enumerate(st.session_state["candidate_dataset"]):
- st.text_input(
- f"Question {i}",
- dataset["question"],
- disabled=True,
- key=f"candidate_dataset_question_{i}",
- )
- st.multiselect(
- f"Categories {i}",
- options=dataset["categories"],
- default=dataset["categories"],
- disabled=True,
- key=f"candidate_dataset_categories_{i}",
- )
- st.multiselect(
- f"Context {i}",
- options=dataset["context"],
- default=dataset["context"],
- disabled=True,
- key=f"candidate_dataset_context_{i}",
- )
- st.markdown(f"SQL {i}")
- st.code(prettify_sql(dataset["sql"]), language="sql", line_numbers=True)
- st.button(
- "Remove",
- key=f"remove_{i}",
- on_click=on_click_remove_candidate_dataset_button,
- args=(i,),
- )
- st.markdown("---")
-
- with st.popover("Save as Evaluation Dataset", use_container_width=True):
- file_name = st.text_input(
- "File Name",
- f"eval_dataset_{datetime.today().strftime('%Y_%m_%d')}.toml",
- key="eval_dataset_file_name",
- )
- download_btn = st.download_button(
- "Download",
- get_eval_dataset_in_toml_string(
- st.session_state["mdl_json"],
- st.session_state["candidate_dataset"],
- ),
- file_name=file_name,
- key="download_eval_dataset_confirmed",
- disabled=not st.session_state["candidate_dataset"],
- )
- if download_btn:
- st.toast("Downloading the evaluation dataset...")
diff --git a/wren-ai-service/eval/data_curation/utils.py b/wren-ai-service/eval/data_curation/utils.py
deleted file mode 100644
index 1dc6aa76a..000000000
--- a/wren-ai-service/eval/data_curation/utils.py
+++ /dev/null
@@ -1,274 +0,0 @@
-import asyncio
-import base64
-import logging
-import os
-import re
-import sys
-from pathlib import Path
-from typing import List, Tuple
-
-import aiohttp
-import orjson
-import sqlparse
-import streamlit as st
-from dotenv import load_dotenv
-from openai import AsyncClient
-
-# add wren-ai-service to sys.path
-sys.path.append(f"{Path().parent.parent.resolve()}")
-from eval.utils import (
- get_contexts_from_sql,
- get_data_from_wren_engine,
- get_ddl_commands,
- get_documents_given_contexts,
-)
-from src.pipelines.indexing.db_schema import DDLChunker
-
-load_dotenv()
-
-WREN_IBIS_ENDPOINT = os.getenv("WREN_IBIS_ENDPOINT", "http://localhost:8000")
-WREN_ENGINE_ENDPOINT = os.getenv("WREN_ENGINE_ENDPOINT", "http://localhost:8080")
-DATA_SOURCES = ["bigquery", "duckdb"]
-TIMEOUT_SECONDS = 60
-ddl_converter = DDLChunker()
-logger = logging.getLogger("wren-ai-service")
-
-
-async def is_sql_valid(
- sql: str,
- data_source: str,
- mdl_json: dict,
- connection_info: dict,
- api_endpoint: str,
- timeout: float = TIMEOUT_SECONDS,
-) -> Tuple[bool, str]:
- sql = sql.rstrip(";") if sql.endswith(";") else sql
-
- if data_source == "duckdb":
- async with aiohttp.request(
- "GET",
- f"{api_endpoint}/v1/mdl/dry-run",
- json={
- "sql": remove_limit_statement(sql),
- "manifest": mdl_json,
- "limit": 1,
- },
- timeout=aiohttp.ClientTimeout(total=timeout),
- ) as response:
- if response.status == 200:
- return True, None
-
- res = await response.json()
- return False, res
- else:
- async with aiohttp.request(
- "POST",
- f"{api_endpoint}/v3/connector/{data_source}/query?dryRun=true",
- json={
- "sql": remove_limit_statement(sql),
- "manifestStr": base64.b64encode(orjson.dumps(mdl_json)).decode(),
- "connectionInfo": connection_info,
- },
- timeout=aiohttp.ClientTimeout(total=timeout),
- ) as response:
- if response.status == 204:
- return True, None
- res = await response.text()
-
- return False, res
-
-
-async def get_validated_question_sql_pairs(
- question_sql_pairs: list[dict],
- data_source: str,
- mdl_json: dict,
- connection_info: dict,
-) -> list[dict]:
- tasks = []
-
- async with aiohttp.ClientSession():
- for question_sql_pair in question_sql_pairs:
- task = asyncio.ensure_future(
- is_sql_valid(
- question_sql_pair["sql"],
- data_source,
- mdl_json,
- connection_info,
- WREN_ENGINE_ENDPOINT
- if data_source == "duckdb"
- else WREN_IBIS_ENDPOINT,
- )
- )
- tasks.append(task)
-
- results = await asyncio.gather(*tasks)
- return [
- {
- **question_sql_pairs[i],
- "context": [],
- "is_valid": valid,
- "error": error,
- }
- for i, (valid, error) in enumerate(results)
- ]
-
-
-async def get_contexts_from_sqls(
- sqls: list[str],
- mdl_json: dict,
- api_endpoint: str = WREN_ENGINE_ENDPOINT,
- timeout: float = TIMEOUT_SECONDS,
-) -> list[list[str]]:
- async with aiohttp.ClientSession():
- tasks = []
- for sql in sqls:
- task = asyncio.ensure_future(
- get_contexts_from_sql(
- sql,
- mdl_json,
- api_endpoint,
- timeout,
- )
- )
- tasks.append(task)
-
- results = await asyncio.gather(*tasks)
-
- return results
-
-
-async def get_question_sql_pairs(
- llm_client: AsyncClient,
- llm_model: str,
- mdl_json: dict,
- custom_instructions: str,
- data_source: str,
- connection_info: dict,
- num_pairs: int = 10,
-) -> list[dict]:
- messages = [
- {
- "role": "system",
- "content": "",
- },
- {
- "role": "user",
- "content": f"""
-### TASK ###
-Given the database DDL, generate {num_pairs} of the questions and corresponding SQL queries.
-
-### Output Format ###
-{{
- "results": [
- {{
- "question": ,
- "sql":
- }},
- {{
- "question": ,
- "sql":
- }},
- ...
- ]
-}}
-
-### Custom Instructions ###
-
-{custom_instructions}
-
-### Input ###
-Data Model: {"\n\n".join(get_ddl_commands(mdl_json))}
-
-Generate {num_pairs} of the questions and corresponding SQL queries according to the Output Format in JSON
-Think step by step
-""",
- },
- ]
-
- try:
- response = await llm_client.chat.completions.create(
- model=llm_model,
- messages=messages,
- response_format={"type": "json_object"},
- max_tokens=4096,
- temperature=0,
- )
-
- results = orjson.loads(response.choices[0].message.content)["results"]
- question_sql_pairs = await get_validated_question_sql_pairs(
- results,
- data_source=data_source,
- mdl_json=mdl_json,
- connection_info=connection_info,
- )
- sqls = [question_sql_pair["sql"] for question_sql_pair in question_sql_pairs]
- contexts = await get_contexts_from_sqls(sqls, mdl_json)
- documents = get_documents_given_contexts(contexts, mdl_json)
- sqls_data = await get_data_from_wren_engine_with_sqls(
- sqls,
- data_source,
- mdl_json,
- connection_info,
- WREN_ENGINE_ENDPOINT
- if st.session_state["data_source"] == "duckdb"
- else WREN_IBIS_ENDPOINT,
- )
- return [
- {
- **quesiton_sql_pair,
- "context": context,
- "data": sql_data,
- "document": document,
- }
- for quesiton_sql_pair, context, sql_data, document in zip(
- question_sql_pairs, contexts, sqls_data, documents
- )
- ]
- except Exception as e:
- logger.error(e)
- st.error(f"Error generating question-sql-pairs: {e}")
- return []
-
-
-def prettify_sql(sql: str) -> str:
- return sqlparse.format(
- sql,
- reindent=True,
- keyword_case="upper",
- )
-
-
-async def get_data_from_wren_engine_with_sqls(
- sqls: List[str],
- data_source: str,
- mdl_json: dict,
- connection_info: dict,
- api_endpoint: str,
- timeout: float = TIMEOUT_SECONDS,
-) -> List[dict]:
- assert data_source in DATA_SOURCES, f"Invalid data source: {data_source}"
-
- async with aiohttp.ClientSession():
- tasks = []
- for sql in sqls:
- task = asyncio.ensure_future(
- get_data_from_wren_engine(
- sql=sql,
- mdl_json=mdl_json,
- api_endpoint=api_endpoint,
- data_source=data_source,
- connection_info=connection_info,
- timeout=timeout,
- limit=50,
- )
- )
- tasks.append(task)
-
- return await asyncio.gather(*tasks)
-
-
-def remove_limit_statement(sql: str) -> str:
- pattern = r"\s*LIMIT\s+\d+(\s*;?\s*--.*|\s*;?\s*)$"
- modified_sql = re.sub(pattern, "", sql, flags=re.IGNORECASE)
-
- return modified_sql
diff --git a/wren-ai-service/eval/dataset/.gitignore b/wren-ai-service/eval/dataset/.gitignore
deleted file mode 100644
index c96a04f00..000000000
--- a/wren-ai-service/eval/dataset/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore
\ No newline at end of file
diff --git a/wren-ai-service/eval/dspy_modules/__init__.py b/wren-ai-service/eval/dspy_modules/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/wren-ai-service/eval/dspy_modules/ask_generation.py b/wren-ai-service/eval/dspy_modules/ask_generation.py
deleted file mode 100644
index c21db8863..000000000
--- a/wren-ai-service/eval/dspy_modules/ask_generation.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import dspy
-
-
-class AskGenerationSignatureV1(dspy.Signature):
- """Given a user query that is ambiguous in nature, your task is to interpret the query in various plausible ways and \
-generate three SQL statements that could potentially answer each interpreted version of the queries and within-10-words summary. \
-Provide three different interpretations and corresponding SQL queries that reflect these interpretations. \
-Ensure that your SQL queries are diverse, covering a range of possible meanings behind the ambiguous query. \
-
-The output should be in the following JSON format:
-
-{
- "results": [
- {"sql": , "summary": },
- {"sql": , "summary": },
- {"sql": , "summary": }
- ]
-}
-"""
-
- question = dspy.InputField()
- context = dspy.InputField(description="List of database schema documents")
- answer = dspy.OutputField()
-
-
-class AskGenerationV1(dspy.Module):
- def __init__(self):
- super().__init__()
- self.generate_answer = dspy.ChainOfThought(AskGenerationSignatureV1)
-
- def forward(self, question, context):
- prediction = self.generate_answer(question=question, context=context)
- return dspy.Prediction(context=context, answer=prediction.answer)
diff --git a/wren-ai-service/eval/dspy_modules/prompt_optimizer.py b/wren-ai-service/eval/dspy_modules/prompt_optimizer.py
deleted file mode 100644
index 47a68ec25..000000000
--- a/wren-ai-service/eval/dspy_modules/prompt_optimizer.py
+++ /dev/null
@@ -1,183 +0,0 @@
-import argparse
-import os
-import re
-import sys
-from datetime import datetime
-from pathlib import Path
-from typing import Callable, Tuple
-
-import dotenv
-import dspy
-import dspy.evaluate
-import dspy.teleprompt
-
-sys.path.append(f"{Path().parent.resolve()}")
-import src.utils as utils
-from eval.dspy_modules.ask_generation import AskGenerationV1
-from eval.utils import parse_toml
-
-
-def parse_args() -> Tuple[str]:
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "--file",
- "-F",
- type=str,
- required=True,
- help="Eval dataset file name in the eval/dataset folder",
- )
- parser.add_argument(
- "--program_file",
- "-P",
- type=str,
- help="Optimized program file name in the eval/optimized folder",
- )
- parser.add_argument(
- "--optimize",
- action=argparse.BooleanOptionalAction,
- help="Whether to optimize the program or not",
- )
- parser.add_argument(
- "--eval",
- action=argparse.BooleanOptionalAction,
- help="Whether to evaluate the program or not based on the devset of eval dataset",
- )
-
- return parser.parse_args()
-
-
-optimizer_parameters = {
- "evaluator": None,
- "metrics": None,
- "meta": None,
- "predictions": None,
-}
-
-
-def configure_llm_provider(llm: str, api_key: str):
- dspy.settings.configure(lm=dspy.LM(model=llm, api_key=api_key))
-
-
-def clean_sql(sql: str) -> str:
- return re.sub("[ \t\n]+", " ", sql)
-
-
-def prepare_dataset(path: str, train_ratio: float = 0.5):
- eval_dataset = parse_toml(f"eval/dataset/{path}")["eval_dataset"]
-
- dspy_dataset = []
- for data in eval_dataset:
- dspy_dataset.append(
- dspy.Example(
- context=[str(doc["content"]) for doc in data["document"]],
- question=str(data["question"]),
- answer=clean_sql(str(data["sql"])),
- ).with_inputs("question", "context")
- )
-
- train_size = int(len(dspy_dataset) * train_ratio)
- _train = dspy_dataset[:train_size]
- _dev = dspy_dataset[train_size:]
- return _train, _dev
-
-
-# Validation logic: check that the predicted answer is correct.
-# Also check that the retrieved context does actually contain that answer.
-def validate_context_and_answer(example, pred, trace=None):
- if optimizer_parameters["predictions"] is None:
- # if we don't have metric from eval module, we use the default metric
- answer_EM = dspy.evaluate.answer_exact_match(example, pred)
- answer_PM = dspy.evaluate.answer_passage_match(example, pred)
- return answer_EM and answer_PM
- else:
- prediction = optimizer_parameters["predictions"][0]
- prediction.input = example.question
- prediction.expected_output = example.answer
- prediction.context = example.context
- prediction["type"] = "execution"
- prediction.actual_output = pred.answer
- # reuse the first predict result to optimize the dspy module
- optimizer_parameters["evaluator"].eval(
- optimizer_parameters["meta"], [prediction]
- )
- sum_score = 0
- for metric in optimizer_parameters["metrics"].get("metrics"):
- sum_score += metric.score
- return sum_score
-
-
-def optimize(
- module: dspy.Module,
- optimizer: dspy.teleprompt.Teleprompter,
- trainset: list,
- metric: Callable,
-):
- optimizer = optimizer(metric=metric)
- return optimizer.compile(module(), trainset=trainset)
-
-
-def build_optimizing_module(trainset):
- module = optimize(
- AskGenerationV1,
- dspy.teleprompt.BootstrapFewShot,
- trainset=trainset,
- metric=validate_context_and_answer,
- )
- path = f"eval/optimized/{AskGenerationV1.__name__}_optimized_{datetime.now().strftime("%Y_%m_%d_%H%M%S")}.json"
- directory = os.path.dirname(path)
- if directory and not os.path.exists(directory):
- os.makedirs(directory)
- module.save(path)
- return module
-
-
-if __name__ == "__main__":
- args = parse_args()
- path = f"eval/dataset/{args.file}"
- optimized_program_file = args.program_file
- should_optimize = args.optimize
- should_eval = args.eval
-
- dotenv.load_dotenv()
- utils.load_env_vars()
-
- configure_llm_provider(os.getenv("GENERATION_MODEL"), os.getenv("OPENAI_API_KEY"))
-
- trainset, devset = prepare_dataset(path)
-
- if optimized_program_file:
- module = AskGenerationV1()
- module.load(f"eval/optimized/{optimized_program_file}")
- elif should_optimize:
- module = build_optimizing_module(trainset)
- else:
- module = AskGenerationV1()
-
- if should_eval:
- evaluator = dspy.evaluate.Evaluate(
- devset=devset,
- metric=validate_context_and_answer,
- display_progress=True,
- display_table=True,
- return_outputs=True,
- )
-
- results = evaluator(
- module,
- metric=validate_context_and_answer,
- display_progress=True,
- display_table=True,
- return_all_scores=True,
- return_outputs=True,
- )
- for result in results:
- if isinstance(result, list):
- for item in result:
- if isinstance(item, tuple):
- if len(item) == 3:
- print(item[0])
- print(f"Question: {item[0].get('question')}")
- print(f"Context: {item[0].get('context')}")
- print(item[1])
- print(f"Answer: {item[1].get('answer')}")
- print(f"Context: {item[1].get('context')}")
diff --git a/wren-ai-service/eval/evaluation.py b/wren-ai-service/eval/evaluation.py
deleted file mode 100644
index 07b0c4bd0..000000000
--- a/wren-ai-service/eval/evaluation.py
+++ /dev/null
@@ -1,200 +0,0 @@
-import argparse
-import sys
-from pathlib import Path
-from typing import Tuple
-
-from deepeval import evaluate
-from deepeval.evaluate import TestResult
-from deepeval.test_case import LLMTestCase
-from langfuse import Langfuse
-from langfuse.decorators import langfuse_context, observe
-
-sys.path.append(f"{Path().parent.resolve()}")
-import traceback
-
-import eval.pipelines as pipelines
-import src.providers as provider
-from eval import EvalSettings
-from eval.utils import parse_toml, trace_metadata
-from src import utils
-
-
-def formatter(prediction: dict, meta: dict) -> dict:
- """
- Formats the prediction result to be used as evaluation input.
-
- This function takes a prediction dictionary and a meta dictionary,
- processes them to extract relevant information, and returns a formatted
- dictionary that serves as input for evaluation. It includes details such
- as input, actual and expected outputs, context, and additional metadata.
-
- Args:
- prediction (dict): A dictionary containing prediction details.
- meta (dict): A dictionary containing metadata information.
-
- Returns:
- dict: A formatted dictionary containing evaluation input data.
- """
- retrieval_context = [str(context) for context in prediction["retrieval_context"]]
- context = [str(context) for context in prediction["context"]]
- enable_spider_metrics = "spider" in meta.get("evaluation_dataset", "").lower()
- enable_rewrite = any(
- dataset in meta.get("evaluation_dataset", "").lower() for dataset in ["spider"]
- )
-
- return {
- "input": prediction["input"],
- "actual_output": (
- prediction.get("actual_output", {})
- .get("post_process", {})
- .get("valid_generation_result", {})
- .get("sql", "")
- ),
- "expected_output": prediction["expected_output"],
- "retrieval_context": retrieval_context,
- "context": context,
- "reasoning": prediction.get("reasoning", ""),
- "additional_metadata": {
- "trace_id": prediction["trace_id"],
- "trace_url": prediction["trace_url"],
- "catalog": meta.get("catalog", None),
- "enable_spider_metrics": enable_spider_metrics,
- "enable_rewrite": enable_rewrite,
- },
- }
-
-
-def parse_args() -> Tuple[str]:
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "--file",
- "-F",
- type=str,
- help="Eval the prediction result in the outputs/predictions directory",
- )
- parser.add_argument(
- "--semantics",
- "-S",
- default=False,
- action=argparse.BooleanOptionalAction,
- help="Whether use the LLM(OpenAI's gpt-4o-mini) to help check semantics of sqls to improve accuracy metrics",
- )
- parser.add_argument(
- "--training-dataset",
- "-T",
- default=None,
- help="Use the training dataset to build a dspy optimized module",
- )
- return parser.parse_args()
-
-
-class Evaluator:
- def __init__(self, metrics: list, **kwargs):
- self._score_collector = {}
- self._langfuse = Langfuse()
- self._metrics = metrics
- self._failed_count = 0
- self._post_metrics = kwargs.get("post_metrics", [])
-
- def eval(self, meta: dict, predictions: list) -> None:
- for prediction in predictions:
- try:
- test_case = LLMTestCase(**formatter(prediction, meta))
- result = evaluate(
- [test_case], self._metrics, ignore_errors=True
- ).test_results[0]
- self._score_metrics(test_case, result)
- [metric.collect(test_case, result) for metric in self._post_metrics]
- except Exception:
- self._failed_count += 1
- traceback.print_exc()
-
- self._average_score(meta)
-
- def _score_metrics(self, test_case: LLMTestCase, result: TestResult) -> None:
- for metric in result.metrics_data:
- name = metric.name
- score = metric.score or 0
-
- self._langfuse.score(
- trace_id=test_case.additional_metadata["trace_id"],
- name=name,
- value=score,
- comment=metric.reason or metric.error,
- source="EVAL",
- )
-
- if name not in self._score_collector:
- self._score_collector[name] = []
-
- self._score_collector[name].append(score)
-
- @observe(name="Summary Trace", capture_input=False, capture_output=False)
- def _average_score(self, meta: dict) -> None:
- langfuse_context.update_current_trace(
- session_id=meta.get("session_id"),
- user_id=meta.get("user_id"),
- metadata=trace_metadata(meta, type="summary"),
- )
-
- summary = {
- "query_count": meta["query_count"],
- "expected_batch_size": meta["expected_batch_size"],
- "actual_batch_size": meta["actual_batch_size"],
- "valid_eval_count": meta["actual_batch_size"] - self._failed_count,
- }
- langfuse_context.update_current_observation(output=summary)
-
- for name, scores in self._score_collector.items():
- langfuse_context.score_current_trace(
- name=name,
- value=sum(scores) / len(scores),
- comment=f"Average score for {name}",
- )
-
- for metric in self._post_metrics:
- langfuse_context.score_current_trace(
- name=metric.__name__,
- value=metric.measure(),
- comment=f"Average score for {metric.__name__}",
- )
-
-
-if __name__ == "__main__":
- args = parse_args()
-
- settings = EvalSettings()
- pipe_components = provider.generate_components(settings.components)
- utils.init_langfuse(settings)
-
- predicted_file = parse_toml(f"outputs/predictions/{args.file}")
- meta = predicted_file["meta"]
- predictions = predicted_file["predictions"]
-
- dataset = parse_toml(meta["evaluation_dataset"])
- metrics = pipelines.metrics_initiator(
- meta["pipeline"], dataset, pipe_components, args.semantics, settings
- )
-
- evaluator = Evaluator(**metrics)
- evaluator.eval(meta, predictions)
- # if args.training_dataset:
- # # todo: for now comment dspy related code
- # optimizer_parameters["evaluator"] = evaluator
- # optimizer_parameters["metrics"] = metrics
- # optimizer_parameters["meta"] = meta
- # optimizer_parameters["predictions"] = predictions
- # configure_llm_provider(
- # os.getenv("GENERATION_MODEL"), os.getenv("OPENAI_API_KEY")
- # )
- # trainset, devset = prepare_dataset(args.training_dataset)
- # build_optimizing_module(trainset)
- # else:
- # evaluator.eval(meta, predictions)
-
- langfuse_context.flush()
-
- if meta["langfuse_url"]:
- print(
- f"\n\nYou can view the evaluation result in Langfuse at {meta['langfuse_url']}/sessions/{meta['session_id']}"
- )
diff --git a/wren-ai-service/eval/mdl_to_csv.py b/wren-ai-service/eval/mdl_to_csv.py
deleted file mode 100644
index c6a750883..000000000
--- a/wren-ai-service/eval/mdl_to_csv.py
+++ /dev/null
@@ -1,125 +0,0 @@
-import argparse
-import csv
-from pathlib import Path
-
-import orjson
-
-
-def gen_eval_preparation_data_from_json_to_csv(mdl_path: str):
- assert Path(mdl_path).exists(), f"File not found: {mdl_path}"
-
- with open(mdl_path) as file:
- mdl = orjson.loads(file.read())
-
- csv_data = [
- [
- "table",
- "table alias",
- "table description",
- "column",
- "column alias",
- "column description",
- ]
- ]
- for model in mdl["models"]:
- for column in model["columns"]:
- csv_data.append(
- [
- model["name"],
- model.get("properties", {}).get("displayName", ""),
- model.get("properties", {}).get("description", ""),
- column["name"],
- column.get("properties", {}).get("displayName", ""),
- column.get("properties", {}).get("description", ""),
- ]
- )
-
- with open(f"{Path(mdl_path).stem}.csv", "w", newline="\n") as file:
- writer = csv.writer(file, quoting=csv.QUOTE_MINIMAL)
-
- for row in csv_data:
- writer.writerow(row)
-
-
-def gen_new_mdl_from_csv(mdl_path: str, csv_path: str):
- assert Path(mdl_path).exists(), f"File not found: {mdl_path}"
- assert Path(csv_path).exists(), f"File not found: {csv_path}"
-
- with open(mdl_path) as file:
- mdl = orjson.loads(file.read())
-
- csv_data_by_table = {}
-
- with open(csv_path, newline="\n") as file:
- csv_data = csv.reader(file)
-
- for row in csv_data:
- model_name = row[0]
- if model_name not in csv_data_by_table:
- csv_data_by_table[model_name] = {
- "model": {
- "displayName": row[1],
- "description": row[2],
- },
- "columns": {},
- }
-
- csv_data_by_table[model_name]["columns"][row[3]] = {
- "displayName": row[4],
- "description": row[5],
- }
-
- new_models = []
- for model in mdl["models"]:
- if model["name"] in csv_data_by_table:
- if "properties" not in model:
- model["properties"] = {}
- if csv_data_by_table[model["name"]]["model"]["displayName"]:
- model["properties"]["displayName"] = csv_data_by_table[
- model["name"]
- ]["model"]["displayName"]
- if csv_data_by_table[model["name"]]["model"]["description"]:
- model["properties"]["description"] = csv_data_by_table[
- model["name"]
- ]["model"]["description"]
-
- new_columns = []
- for column in model["columns"]:
- if column["name"] in csv_data_by_table[model["name"]]["columns"]:
- if "properties" not in column:
- column["properties"] = {}
- if csv_data_by_table[model["name"]]["columns"][column["name"]][
- "displayName"
- ]:
- column["properties"]["displayName"] = csv_data_by_table[
- model["name"]
- ]["columns"][column["name"]]["displayName"]
- if csv_data_by_table[model["name"]]["columns"][column["name"]][
- "description"
- ]:
- column["properties"]["description"] = csv_data_by_table[
- model["name"]
- ]["columns"][column["name"]]["description"]
- new_columns.append(column)
-
- model["columns"] = new_columns
- new_models.append(model)
-
- mdl["models"] = new_models
-
- with open(f"{Path(mdl_path).stem}_new.json", "w") as file:
- file.write(orjson.dumps(mdl).decode())
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "--mdl-path", type=str, help="Path to the MDL JSON file", required=True
- )
- parser.add_argument("--csv-path", type=str, help="Path to the input CSV file")
- args = parser.parse_args()
-
- if args.mdl_path and not args.csv_path:
- gen_eval_preparation_data_from_json_to_csv(args.mdl_path)
- elif args.mdl_path and args.csv_path:
- gen_new_mdl_from_csv(args.mdl_path, args.csv_path)
diff --git a/wren-ai-service/eval/metrics/__init__.py b/wren-ai-service/eval/metrics/__init__.py
deleted file mode 100644
index 084c97be2..000000000
--- a/wren-ai-service/eval/metrics/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from .accuracy import AccuracyMetric, AccuracyMultiCandidateMetric
-from .answer_relevancy import AnswerRelevancyMetric
-from .context_precision import ContextualPrecisionMetric
-from .context_recall import ContextualRecallMetric
-from .context_relevancy import ContextualRelevancyMetric
-from .faithfulness import FaithfulnessMetric
-from .llm import (
- QuestionToReasoningJudge,
- ReasoningToSqlJudge,
- SqlSemanticsJudge,
-)
-from .spider.exact_match import ExactMatchAccuracy
-from .spider.exec_match import ExecutionAccuracy
-
-__all__ = [
- "AccuracyMetric",
- "AccuracyMultiCandidateMetric",
- "AnswerRelevancyMetric",
- "ContextualPrecisionMetric",
- "ContextualRecallMetric",
- "ContextualRelevancyMetric",
- "FaithfulnessMetric",
- "ExactMatchAccuracy",
- "ExecutionAccuracy",
- "QuestionToReasoningJudge",
- "ReasoningToSqlJudge",
- "SqlSemanticsJudge",
-]
diff --git a/wren-ai-service/eval/metrics/accuracy.py b/wren-ai-service/eval/metrics/accuracy.py
deleted file mode 100644
index 61bcfb916..000000000
--- a/wren-ai-service/eval/metrics/accuracy.py
+++ /dev/null
@@ -1,205 +0,0 @@
-import asyncio
-import re
-import traceback
-
-import orjson
-import pandas as pd
-from deepeval.evaluate import TestResult
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-from deprecated import deprecated
-
-from eval.utils import get_data_from_wren_engine, get_openai_client
-
-
-class AccuracyMetric(BaseMetric):
- def __init__(self, engine_info: dict, enable_semantics_comparison: bool = False):
- self.threshold = 0
- self.score = 0
- self.engine_info = engine_info
- self.enable_semantics_comparison = enable_semantics_comparison
- if self.enable_semantics_comparison:
- self._openai_client = get_openai_client()
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- def _is_subset(self, expected: pd.DataFrame, actual: pd.DataFrame) -> bool:
- if not set(expected.columns).issubset(set(actual.columns)):
- return False
-
- common_columns = sorted(expected.columns)
-
- expected_sorted = expected[common_columns]
- actual_sorted = actual[common_columns]
- # Ensure that the data types are the same
- actual_sorted = actual_sorted.astype(expected_sorted.dtypes.to_dict())
-
- merged = pd.merge(
- actual_sorted,
- expected_sorted,
- on=common_columns,
- how="left",
- indicator=True,
- )
- return all(merged["_merge"] == "both")
-
- def _count_partial_matches(
- self, expected: pd.DataFrame, actual: pd.DataFrame
- ) -> int:
- intersection = set(expected.columns).intersection(set(actual.columns))
- common_columns = sorted(intersection)
- if not common_columns:
- return 0
-
- expected_sorted = expected[common_columns]
- actual_sorted = actual[common_columns]
- # Ensure that the data types are the same
- actual_sorted = actual_sorted.astype(expected_sorted.dtypes.to_dict())
-
- merged = pd.merge(
- actual_sorted,
- expected_sorted,
- on=common_columns,
- how="left",
- indicator=True,
- )
- if all(merged["_merge"] == "both"):
- return len(intersection) / len(expected.columns)
- else:
- return 0
-
- def _rewrite_sql(self, sql: str) -> str:
- # Pattern to match double quotes after WHERE clause, including multiple occurrences
- pattern = r'(WHERE\s+.*?)(")(.+?)(")(.*)$'
- replacement = r"\1'\3'\5"
-
- # Apply the replacement repeatedly until no more changes
- new_sql = re.sub(pattern, replacement, sql, flags=re.IGNORECASE | re.DOTALL)
- while new_sql != sql:
- sql = new_sql
- new_sql = re.sub(pattern, replacement, sql, flags=re.IGNORECASE | re.DOTALL)
-
- return sql
-
- async def _retrieve_data(self, sql: str) -> pd.DataFrame:
- response = await get_data_from_wren_engine(sql=sql, **self.engine_info)
-
- df = pd.DataFrame(**response)
- sorted_columns = sorted(df.columns)
- return df[sorted_columns].sort_values(by=sorted_columns)
-
- async def _check_sql_semantics(self, expected_sql: str, actual_sql: str):
- _system_prompt = (
- "### TASK ### \n"
- + "You are a great data anlyst, please carefully check the semantics of two given SQLs if they are the same. \n"
- + "The output should be a JSON format with the following schema: \n"
- + "{ \n"
- + ' "reasoning": \n'
- + ' "same": \n'
- + "}"
- )
-
- _user_prompt = (
- "### QUESTION ### \n"
- + f"Expected SQL: {expected_sql} \n"
- + f"Actual SQL: {actual_sql} \n"
- + "\n"
- + "Please think step by step"
- )
-
- response = await self._openai_client.chat.completions.create(
- model="gpt-4o-mini",
- messages=[
- {"role": "system", "content": _system_prompt},
- {"role": "user", "content": _user_prompt},
- ],
- response_format={"type": "json_object"},
- )
-
- print(
- f"response of _check_sql_semantics: {response.choices[0].message.content}"
- )
-
- return 1 if orjson.loads(response.choices[0].message.content)["same"] else 0
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- try:
- enable_rewrite = test_case.additional_metadata.get("enable_rewrite", False)
- rewritten_expected_output = test_case.expected_output
-
- if enable_rewrite:
- rewritten_expected_output = self._rewrite_sql(test_case.expected_output)
-
- expected_dataset = await self._retrieve_data(rewritten_expected_output)
- actual_dataset = await self._retrieve_data(test_case.actual_output)
-
- print(f"expected columns: {set(expected_dataset.columns)}")
- print(f"actual columns: {set(actual_dataset.columns)}")
-
- if expected_dataset.equals(actual_dataset) or self._is_subset(
- expected_dataset, actual_dataset
- ):
- self.success = True
- self.score = 1
- return self.score
-
- self.score = self._count_partial_matches(expected_dataset, actual_dataset)
- # use llm to check sql semantics
- if self.score == 0 and self.enable_semantics_comparison:
- # TODO: we may need to upload the sql semantics result to langfuse
- print(f"before _check_sql_semantics: {self.score}")
- print(f"expected sql: {rewritten_expected_output}")
- print(f"actual sql: {test_case.actual_output}")
- self.score = await self._check_sql_semantics(
- rewritten_expected_output, test_case.actual_output
- )
- print(f"after _check_sql_semantics: {self.score}")
- except Exception as e:
- self.error = f"Error occurred while evaluating the metric: {e}"
- traceback.print_exc()
-
- # if didn't pass any of the above checks
- self.success = False
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "Accuracy(column-based)"
-
-
-@deprecated(
- reason="We don't generate multiple candidates for Text to SQL task, so don't need this metric"
-)
-class AccuracyMultiCandidateMetric(BaseMetric):
- def __init__(self):
- self.threshold = 0
- self.score = 0
- self._questions = {}
-
- def collect(self, test_case: LLMTestCase, result: TestResult):
- for metric in result.metrics_data:
- if metric.name != "Accuracy(column-based)":
- continue
-
- # or 0 to avoid when metric.error is exist
- self._questions[test_case.input] = (
- self._questions.get(test_case.input, 0) or metric.score or 0
- )
-
- def measure(self):
- if not self._questions:
- return 0
- self.score = sum(self._questions.values()) / len(self._questions)
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "Accuracy(question-based)"
diff --git a/wren-ai-service/eval/metrics/answer_relevancy.py b/wren-ai-service/eval/metrics/answer_relevancy.py
deleted file mode 100644
index c1e16258e..000000000
--- a/wren-ai-service/eval/metrics/answer_relevancy.py
+++ /dev/null
@@ -1,38 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-from eval.utils import get_contexts_from_sql
-
-
-class AnswerRelevancyMetric(BaseMetric):
- def __init__(self, engine_info: dict):
- self.threshold = 0
- self.score = 0
- self.engine_info = engine_info
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- actual_units = await get_contexts_from_sql(
- sql=test_case.actual_output, **self.engine_info
- )
-
- expected_units = await get_contexts_from_sql(
- sql=test_case.expected_output, **self.engine_info
- )
-
- intersection = set(actual_units) & set(expected_units)
- self.score = len(intersection) / len(actual_units)
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "AnswerRelevancy(column-based)"
diff --git a/wren-ai-service/eval/metrics/context_precision.py b/wren-ai-service/eval/metrics/context_precision.py
deleted file mode 100644
index 539ae1227..000000000
--- a/wren-ai-service/eval/metrics/context_precision.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-
-class ContextualPrecisionMetric(BaseMetric):
- def __init__(self):
- self.threshold = 0
- self.score = 0
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- context = test_case.context
- retrieval_context = test_case.retrieval_context
-
- intersection = set(context) & set(retrieval_context)
- intersection_count = len(intersection)
-
- if intersection_count == 0:
- self.success = False
- return self.score
-
- n = len(retrieval_context)
- summation = 0
- for k in range(1, n + 1):
- intersection_up_to_k = len(set(context[:k]) & set(retrieval_context[:k]))
- rk = len(set(context[:k]) & set(retrieval_context[k - 1 : k])) > 0
- summation += (intersection_up_to_k / k) * rk
-
- self.score = (1 / intersection_count) * summation
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ContextualPrecision(column-based)"
diff --git a/wren-ai-service/eval/metrics/context_recall.py b/wren-ai-service/eval/metrics/context_recall.py
deleted file mode 100644
index 07cb9f544..000000000
--- a/wren-ai-service/eval/metrics/context_recall.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-from eval.utils import get_contexts_from_sql
-
-
-class ContextualRecallMetric(BaseMetric):
- def __init__(self, engine_info: dict):
- self.threshold = 0
- self.score = 0
- self.engine_info = engine_info
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- expected_units = await get_contexts_from_sql(
- sql=test_case.expected_output, **self.engine_info
- )
-
- intersection = set(test_case.retrieval_context) & set(expected_units)
- self.score = len(intersection) / len(expected_units)
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ContextualRecall(column-based)"
diff --git a/wren-ai-service/eval/metrics/context_relevancy.py b/wren-ai-service/eval/metrics/context_relevancy.py
deleted file mode 100644
index c459960f6..000000000
--- a/wren-ai-service/eval/metrics/context_relevancy.py
+++ /dev/null
@@ -1,27 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-
-class ContextualRelevancyMetric(BaseMetric):
- def __init__(self):
- self.threshold = 0
- self.score = 0
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- intersection = set(test_case.retrieval_context) & set(test_case.context)
- self.score = len(intersection) / len(test_case.retrieval_context)
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ContextualRelevancy(column-based)"
diff --git a/wren-ai-service/eval/metrics/faithfulness.py b/wren-ai-service/eval/metrics/faithfulness.py
deleted file mode 100644
index ff17e0eaf..000000000
--- a/wren-ai-service/eval/metrics/faithfulness.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-from eval.utils import get_contexts_from_sql
-
-
-class FaithfulnessMetric(BaseMetric):
- def __init__(self, engine_info: dict):
- self.threshold = 0
- self.score = 0
- self.engine_info = engine_info
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- actual_units = await get_contexts_from_sql(
- sql=test_case.actual_output, **self.engine_info
- )
- intersection = set(actual_units) & set(test_case.retrieval_context)
- self.score = len(intersection) / len(actual_units)
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "Faithfulness(column-based)"
diff --git a/wren-ai-service/eval/metrics/llm/__init__.py b/wren-ai-service/eval/metrics/llm/__init__.py
deleted file mode 100644
index 2871666a7..000000000
--- a/wren-ai-service/eval/metrics/llm/__init__.py
+++ /dev/null
@@ -1,173 +0,0 @@
-import asyncio
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-from haystack.components.builders.prompt_builder import PromptBuilder
-from pydantic import BaseModel
-
-from src.providers import LLMProvider
-
-
-class EvalResult(BaseModel):
- score: float
- reason: str
-
-
-_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "eval_result",
- "schema": EvalResult.model_json_schema(),
- },
- }
-}
-
-
-def format(response: dict) -> EvalResult:
- reply = response.get("replies", [])[0]
- return EvalResult.model_validate_json(reply)
-
-
-class QuestionToReasoningJudge(BaseMetric):
- _system_prompt = """
- You are an expert evaluator. Your task is to analyze the reasoning provided for a given question and determine if it makes sense.
- Provide a score in the range 0.0~1.0 and a detailed explanation for your evaluation.
- """
- _test_case_prompt = """
- Question:
- {{ question }}
-
- Reasoning:
- {{ reasoning }}
- """
-
- def __init__(self, llm_provider: LLMProvider, **_):
- self.threshold = 0
- self.score = 0
- self.llm_provider = llm_provider
- self.llm = llm_provider.get_generator(
- system_prompt=self._system_prompt,
- generation_kwargs=_MODEL_KWARGS,
- )
- self.prompt_builder = PromptBuilder(template=self._test_case_prompt)
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- prompt = self.prompt_builder.run(
- question=test_case.input,
- reasoning=test_case.reasoning,
- )
- response = await self.llm(prompt.get("prompt"))
- result = format(response)
-
- self.score = result.score
- self.reason = result.reason
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "QuestionToReasoningJudge"
-
-
-class ReasoningToSqlJudge(BaseMetric):
- _system_prompt = """
- You are an expert evaluator. Your task is to analyze the reasoning provided for a given SQL query and determine if it makes sense.
- Provide a score in the range 0.0~1.0 and a detailed explanation for your evaluation.
- """
- _test_case_prompt = """
- Actual Output:
- {{ actual_output }}
-
- Reasoning:
- {{ reasoning }}
- """
-
- def __init__(self, llm_provider: LLMProvider, **_):
- self.threshold = 0
- self.score = 0
- self.llm_provider = llm_provider
- self.llm = llm_provider.get_generator(
- system_prompt=self._system_prompt,
- generation_kwargs=_MODEL_KWARGS,
- )
- self.prompt_builder = PromptBuilder(template=self._test_case_prompt)
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- prompt = self.prompt_builder.run(
- actual_output=test_case.actual_output,
- reasoning=test_case.reasoning,
- )
- response = await self.llm(prompt.get("prompt"))
- result = format(response)
-
- self.score = result.score
- self.reason = result.reason
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ReasoningToSqlJudge"
-
-
-class SqlSemanticsJudge(BaseMetric):
- _system_prompt = """
- You are an expert evaluator. Your task is to analyze the actual SQL query and the expected SQL query and determine if they are semantically equivalent.
- Provide a score in the range 0.0~1.0 and a detailed explanation for your evaluation.
- """
- _test_case_prompt = """
- Actual SQL:
- {{ actual_sql }}
-
- Expected SQL:
- {{ expected_sql }}
- """
-
- def __init__(self, llm_provider: LLMProvider, **_):
- self.threshold = 0
- self.score = 0
- self.llm_provider = llm_provider
- self.llm = llm_provider.get_generator(
- system_prompt=self._system_prompt,
- generation_kwargs=_MODEL_KWARGS,
- )
- self.prompt_builder = PromptBuilder(template=self._test_case_prompt)
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- prompt = self.prompt_builder.run(
- actual_sql=test_case.actual_output,
- expected_sql=test_case.expected_output,
- )
- response = await self.llm(prompt.get("prompt"))
- result = format(response)
-
- self.score = result.score
- self.reason = result.reason
-
- self.success = self.score >= self.threshold
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "SqlSemanticsJudge"
diff --git a/wren-ai-service/eval/metrics/spider/__init__.py b/wren-ai-service/eval/metrics/spider/__init__.py
deleted file mode 100644
index 84673fa4b..000000000
--- a/wren-ai-service/eval/metrics/spider/__init__.py
+++ /dev/null
@@ -1,1013 +0,0 @@
-import asyncio
-import itertools
-import os
-import random
-import re
-import sqlite3
-from collections import defaultdict
-from itertools import chain, product
-from typing import Any, Iterator, List, Set, Tuple
-
-import sqlparse
-import tqdm
-
-from eval.metrics.spider.process_sql import get_sql
-
-# Flag to disable value evaluation
-DISABLE_VALUE = True
-# Flag to disable distinct in select evaluation
-DISABLE_DISTINCT = True
-
-TABLE_TYPE = {
- "sql": "sql",
- "table_unit": "table_unit",
-}
-
-
-WHERE_OPS = (
- "not",
- "between",
- "=",
- ">",
- "<",
- ">=",
- "<=",
- "!=",
- "in",
- "like",
- "is",
- "exists",
-)
-
-
-def get_scores(count, pred_total, label_total):
- if pred_total != label_total:
- return 0, 0, 0
- elif count == pred_total:
- return 1, 1, 1
- return 0, 0, 0
-
-
-def eval_sel(pred, label):
- pred_sel = pred["select"][1]
- label_sel = label["select"][1]
- label_wo_agg = [unit[1] for unit in label_sel]
- pred_total = len(pred_sel)
- label_total = len(label_sel)
- cnt = 0
- cnt_wo_agg = 0
-
- for unit in pred_sel:
- if unit in label_sel:
- cnt += 1
- label_sel.remove(unit)
- if unit[1] in label_wo_agg:
- cnt_wo_agg += 1
- label_wo_agg.remove(unit[1])
-
- return label_total, pred_total, cnt, cnt_wo_agg
-
-
-def eval_where(pred, label):
- pred_conds = [unit for unit in pred["where"][::2]]
- label_conds = [unit for unit in label["where"][::2]]
- label_wo_agg = [unit[2] for unit in label_conds]
- pred_total = len(pred_conds)
- label_total = len(label_conds)
- cnt = 0
- cnt_wo_agg = 0
-
- for unit in pred_conds:
- if unit in label_conds:
- cnt += 1
- label_conds.remove(unit)
- if unit[2] in label_wo_agg:
- cnt_wo_agg += 1
- label_wo_agg.remove(unit[2])
-
- return label_total, pred_total, cnt, cnt_wo_agg
-
-
-def eval_group(pred, label):
- pred_cols = [unit[1] for unit in pred["groupBy"]]
- label_cols = [unit[1] for unit in label["groupBy"]]
- pred_total = len(pred_cols)
- label_total = len(label_cols)
- cnt = 0
- pred_cols = [pred.split(".")[1] if "." in pred else pred for pred in pred_cols]
- label_cols = [
- label.split(".")[1] if "." in label else label for label in label_cols
- ]
- for col in pred_cols:
- if col in label_cols:
- cnt += 1
- label_cols.remove(col)
- return label_total, pred_total, cnt
-
-
-def eval_having(pred, label):
- pred_total = label_total = cnt = 0
- if len(pred["groupBy"]) > 0:
- pred_total = 1
- if len(label["groupBy"]) > 0:
- label_total = 1
-
- pred_cols = [unit[1] for unit in pred["groupBy"]]
- label_cols = [unit[1] for unit in label["groupBy"]]
- if (
- pred_total == label_total == 1
- and pred_cols == label_cols
- and pred["having"] == label["having"]
- ):
- cnt = 1
-
- return label_total, pred_total, cnt
-
-
-def eval_order(pred, label):
- pred_total = label_total = cnt = 0
- if len(pred["orderBy"]) > 0:
- pred_total = 1
- if len(label["orderBy"]) > 0:
- label_total = 1
- if (
- len(label["orderBy"]) > 0
- and pred["orderBy"] == label["orderBy"]
- and (
- (pred["limit"] is None and label["limit"] is None)
- or (pred["limit"] is not None and label["limit"] is not None)
- )
- ):
- cnt = 1
- return label_total, pred_total, cnt
-
-
-def eval_and_or(pred, label):
- pred_ao = pred["where"][1::2]
- label_ao = label["where"][1::2]
- pred_ao = set(pred_ao)
- label_ao = set(label_ao)
-
- if pred_ao == label_ao:
- return 1, 1, 1
- return len(pred_ao), len(label_ao), 0
-
-
-def get_nestedSQL(sql):
- nested = []
- for cond_unit in sql["from"]["conds"][::2] + sql["where"][::2] + sql["having"][::2]:
- if isinstance(cond_unit[3], dict):
- nested.append(cond_unit[3])
- if isinstance(cond_unit[4], dict):
- nested.append(cond_unit[4])
- if sql["intersect"] is not None:
- nested.append(sql["intersect"])
- if sql["except"] is not None:
- nested.append(sql["except"])
- if sql["union"] is not None:
- nested.append(sql["union"])
- return nested
-
-
-def eval_nested(pred, label):
- label_total = 0
- pred_total = 0
- cnt = 0
- if pred is not None:
- pred_total += 1
- if label is not None:
- label_total += 1
- if pred is not None and label is not None:
- cnt += Evaluator().eval_exact_match(pred, label)
- return label_total, pred_total, cnt
-
-
-def eval_IUEN(pred, label):
- lt1, pt1, cnt1 = eval_nested(pred["intersect"], label["intersect"])
- lt2, pt2, cnt2 = eval_nested(pred["except"], label["except"])
- lt3, pt3, cnt3 = eval_nested(pred["union"], label["union"])
- label_total = lt1 + lt2 + lt3
- pred_total = pt1 + pt2 + pt3
- cnt = cnt1 + cnt2 + cnt3
- return label_total, pred_total, cnt
-
-
-def get_keywords(sql):
- res = set()
- if len(sql["where"]) > 0:
- res.add("where")
- if len(sql["groupBy"]) > 0:
- res.add("group")
- if len(sql["having"]) > 0:
- res.add("having")
- if len(sql["orderBy"]) > 0:
- res.add(sql["orderBy"][0])
- res.add("order")
- if sql["limit"] is not None:
- res.add("limit")
- if sql["except"] is not None:
- res.add("except")
- if sql["union"] is not None:
- res.add("union")
- if sql["intersect"] is not None:
- res.add("intersect")
-
- # or keyword
- ao = sql["from"]["conds"][1::2] + sql["where"][1::2] + sql["having"][1::2]
- if len([token for token in ao if token == "or"]) > 0:
- res.add("or")
-
- cond_units = sql["from"]["conds"][::2] + sql["where"][::2] + sql["having"][::2]
- # not keyword
- if len([cond_unit for cond_unit in cond_units if cond_unit[0]]) > 0:
- res.add("not")
-
- # in keyword
- if (
- len(
- [
- cond_unit
- for cond_unit in cond_units
- if cond_unit[1] == WHERE_OPS.index("in")
- ]
- )
- > 0
- ):
- res.add("in")
-
- # like keyword
- if (
- len(
- [
- cond_unit
- for cond_unit in cond_units
- if cond_unit[1] == WHERE_OPS.index("like")
- ]
- )
- > 0
- ):
- res.add("like")
-
- return res
-
-
-def eval_keywords(pred, label):
- pred_keywords = get_keywords(pred)
- label_keywords = get_keywords(label)
- pred_total = len(pred_keywords)
- label_total = len(label_keywords)
- cnt = 0
-
- for k in pred_keywords:
- if k in label_keywords:
- cnt += 1
- return label_total, pred_total, cnt
-
-
-class Evaluator:
- def eval_exact_match(self, pred: dict, label: dict):
- partial_scores = self.eval_partial_match(pred, label)
-
- for key, score in partial_scores.items():
- if score["f1"] != 1:
- return 0
-
- if len(label["from"]["table_units"]) > 0:
- label_tables = sorted(label["from"]["table_units"])
- pred_tables = sorted(pred["from"]["table_units"])
- return label_tables == pred_tables
- return 1
-
- def eval_partial_match(self, pred, label):
- res = {}
-
- label_total, pred_total, cnt, cnt_wo_agg = eval_sel(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["select"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
- acc, rec, f1 = get_scores(cnt_wo_agg, pred_total, label_total)
- res["select(no AGG)"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt, cnt_wo_agg = eval_where(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["where"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
- acc, rec, f1 = get_scores(cnt_wo_agg, pred_total, label_total)
- res["where(no OP)"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_group(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["group(no Having)"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_having(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["group"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_order(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["order"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_and_or(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["and/or"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_IUEN(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["IUEN"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- label_total, pred_total, cnt = eval_keywords(pred, label)
- acc, rec, f1 = get_scores(cnt, pred_total, label_total)
- res["keywords"] = {
- "acc": acc,
- "rec": rec,
- "f1": f1,
- "label_total": label_total,
- "pred_total": pred_total,
- }
-
- return res
-
-
-def rebuild_col_unit_col(valid_col_units, col_unit, kmap):
- if col_unit is None:
- return col_unit
-
- agg_id, col_id, distinct = col_unit
- if col_id in kmap and col_id in valid_col_units:
- col_id = kmap[col_id]
- if DISABLE_DISTINCT:
- distinct = None
- return agg_id, col_id, distinct
-
-
-def rebuild_val_unit_col(valid_col_units, val_unit, kmap):
- if val_unit is None:
- return val_unit
-
- unit_op, col_unit1, col_unit2 = val_unit
- col_unit1 = rebuild_col_unit_col(valid_col_units, col_unit1, kmap)
- col_unit2 = rebuild_col_unit_col(valid_col_units, col_unit2, kmap)
- return unit_op, col_unit1, col_unit2
-
-
-def rebuild_table_unit_col(valid_col_units, table_unit, kmap):
- if table_unit is None:
- return table_unit
-
- table_type, col_unit_or_sql = table_unit
- if isinstance(col_unit_or_sql, tuple):
- col_unit_or_sql = rebuild_col_unit_col(valid_col_units, col_unit_or_sql, kmap)
- return table_type, col_unit_or_sql
-
-
-def rebuild_cond_unit_col(valid_col_units, cond_unit, kmap):
- if cond_unit is None:
- return cond_unit
-
- not_op, op_id, val_unit, val1, val2 = cond_unit
- val_unit = rebuild_val_unit_col(valid_col_units, val_unit, kmap)
- return not_op, op_id, val_unit, val1, val2
-
-
-def rebuild_condition_col(valid_col_units, condition, kmap):
- for idx in range(len(condition)):
- if idx % 2 == 0:
- condition[idx] = rebuild_cond_unit_col(
- valid_col_units, condition[idx], kmap
- )
- return condition
-
-
-def rebuild_select_col(valid_col_units, sel, kmap):
- if sel is None:
- return sel
- distinct, _list = sel
- new_list = []
- for it in _list:
- agg_id, val_unit = it
- new_list.append((agg_id, rebuild_val_unit_col(valid_col_units, val_unit, kmap)))
- if DISABLE_DISTINCT:
- distinct = None
- return distinct, new_list
-
-
-def rebuild_from_col(valid_col_units, from_, kmap):
- if from_ is None:
- return from_
-
- from_["table_units"] = [
- rebuild_table_unit_col(valid_col_units, table_unit, kmap)
- for table_unit in from_["table_units"]
- ]
- from_["conds"] = rebuild_condition_col(valid_col_units, from_["conds"], kmap)
- return from_
-
-
-def rebuild_group_by_col(valid_col_units, group_by, kmap):
- if group_by is None:
- return group_by
-
- return [
- rebuild_col_unit_col(valid_col_units, col_unit, kmap) for col_unit in group_by
- ]
-
-
-def rebuild_order_by_col(valid_col_units, order_by, kmap):
- if order_by is None or len(order_by) == 0:
- return order_by
-
- direction, val_units = order_by
- new_val_units = [
- rebuild_val_unit_col(valid_col_units, val_unit, kmap) for val_unit in val_units
- ]
- return direction, new_val_units
-
-
-def rebuild_sql_col(valid_col_units, sql, kmap):
- if sql is None:
- return sql
-
- sql["select"] = rebuild_select_col(valid_col_units, sql["select"], kmap)
- sql["from"] = rebuild_from_col(valid_col_units, sql["from"], kmap)
- sql["where"] = rebuild_condition_col(valid_col_units, sql["where"], kmap)
- sql["groupBy"] = rebuild_group_by_col(valid_col_units, sql["groupBy"], kmap)
- sql["orderBy"] = rebuild_order_by_col(valid_col_units, sql["orderBy"], kmap)
- sql["having"] = rebuild_condition_col(valid_col_units, sql["having"], kmap)
- sql["intersect"] = rebuild_sql_col(valid_col_units, sql["intersect"], kmap)
- sql["except"] = rebuild_sql_col(valid_col_units, sql["except"], kmap)
- sql["union"] = rebuild_sql_col(valid_col_units, sql["union"], kmap)
-
- return sql
-
-
-# Rebuild SQL functions for value evaluation
-def rebuild_cond_unit_val(cond_unit):
- if cond_unit is None or not DISABLE_VALUE:
- return cond_unit
-
- not_op, op_id, val_unit, val1, val2 = cond_unit
- if not isinstance(val1, dict):
- val1 = None
- else:
- val1 = rebuild_sql_val(val1)
- if not isinstance(val2, dict):
- val2 = None
- else:
- val2 = rebuild_sql_val(val2)
- return not_op, op_id, val_unit, val1, val2
-
-
-def rebuild_condition_val(condition):
- if condition is None or not DISABLE_VALUE:
- return condition
-
- res = []
- for idx, it in enumerate(condition):
- if idx % 2 == 0:
- res.append(rebuild_cond_unit_val(it))
- else:
- res.append(it)
- return res
-
-
-def rebuild_sql_val(sql):
- if sql is None or not DISABLE_VALUE:
- return sql
-
- sql["from"]["conds"] = rebuild_condition_val(sql["from"]["conds"])
- sql["having"] = rebuild_condition_val(sql["having"])
- sql["where"] = rebuild_condition_val(sql["where"])
- sql["intersect"] = rebuild_sql_val(sql["intersect"])
- sql["except"] = rebuild_sql_val(sql["except"])
- sql["union"] = rebuild_sql_val(sql["union"])
-
- return sql
-
-
-# Rebuild SQL functions for foreign key evaluation
-def build_valid_col_units(table_units, schema):
- col_ids = [
- table_unit[1]
- for table_unit in table_units
- if table_unit[0] == TABLE_TYPE["table_unit"]
- ]
- prefixs = [col_id[:-2] for col_id in col_ids]
- valid_col_units = []
- for value in schema.idMap.values():
- if "." in value and value[: value.index(".")] in prefixs:
- valid_col_units.append(value)
- return valid_col_units
-
-
-def rewrite_sql(sql: str) -> str:
- sql = re.sub(r'"([^"]*)"', r"\1", sql)
- sql = re.sub(r"\s+AS\s+\w+", "", sql, flags=re.IGNORECASE)
- sql = re.sub(r"\s+", " ", sql).strip()
-
- return sql
-
-
-def tokenize(sql: str, schema: dict, kmap: dict) -> dict:
- rewritten_sql = rewrite_sql(sql)
-
- try:
- struct = get_sql(schema, rewritten_sql)
- except Exception:
- struct = {
- "except": None,
- "from": {"conds": [], "table_units": []},
- "groupBy": [],
- "having": [],
- "intersect": None,
- "limit": None,
- "orderBy": [],
- "select": [False, []],
- "union": None,
- "where": [],
- }
-
- g_valid_col_units = build_valid_col_units(struct["from"]["table_units"], schema)
- struct = rebuild_sql_val(struct)
- struct = rebuild_sql_col(g_valid_col_units, struct, kmap)
- return struct
-
-
-def build_foreign_key_map(entry):
- cols_orig = entry["column_names_original"]
- tables_orig = entry["table_names_original"]
-
- # rebuild cols corresponding to idmap in Schema
- cols = []
- for col_orig in cols_orig:
- if col_orig[0] >= 0:
- t = tables_orig[col_orig[0]]
- c = col_orig[1]
- cols.append("__" + t.lower() + "." + c.lower() + "__")
- else:
- cols.append("__all__")
-
- def keyset_in_list(k1, k2, k_list):
- for k_set in k_list:
- if k1 in k_set or k2 in k_set:
- return k_set
- new_k_set = set()
- k_list.append(new_k_set)
- return new_k_set
-
- foreign_key_list = []
- foreign_keys = entry["foreign_keys"]
- for fkey in foreign_keys:
- key1, key2 = fkey
- key_set = keyset_in_list(key1, key2, foreign_key_list)
- key_set.add(key1)
- key_set.add(key2)
-
- foreign_key_map = {}
- for key_set in foreign_key_list:
- sorted_list = sorted(list(key_set))
- midx = sorted_list[0]
- for idx in sorted_list:
- foreign_key_map[cols[idx]] = cols[midx]
-
- return foreign_key_map
-
-
-def build_foreign_key_map_from_json(table):
- try:
- import json
-
- with open(table) as f:
- data = json.load(f)
- tables = {}
- for entry in data:
- tables[entry["db_id"]] = build_foreign_key_map(entry)
- return tables
- except Exception as e:
- print(f"Error building foreign key map from JSON: {e}")
- return {}
-
-
-VALUE_NUM_SYMBOL = "VALUERARE"
-
-
-# plug in the values into query with value slots
-def plugin(query_value_replaced: List[str], values_in_order: List[str]) -> str:
- q_length = len(query_value_replaced)
- query_w_values = query_value_replaced[:]
- value_idx = [
- idx
- for idx in range(q_length)
- if query_value_replaced[idx] == VALUE_NUM_SYMBOL.lower()
- ]
- assert len(value_idx) == len(values_in_order)
-
- for idx, value in zip(value_idx, values_in_order):
- query_w_values[idx] = value
- return " ".join(query_w_values)
-
-
-# a generator generating all possible ways of
-# filling values into predicted query
-def plugin_all_permutations(
- query_value_replaced: List[str], values: Set[str]
-) -> Iterator[str]:
- num_slots = len([v for v in query_value_replaced if v == VALUE_NUM_SYMBOL.lower()])
- for values in itertools.product(*[list(values) for _ in range(num_slots)]):
- yield plugin(query_value_replaced, list(values))
-
-
-# strip_query, reformat_query and replace values
-# were implemented by Yu Tao for processing CoSQL
-def strip_query(query: str) -> Tuple[List[str], List[str]]:
- query_keywords, all_values = [], []
-
- # then replace all stuff enclosed by "" with a numerical value to get it marked as {VALUE}
-
- # Tao's implementation is commented out here.
- """
- str_1 = re.findall("\"[^\"]*\"", query)
- str_2 = re.findall("\'[^\']*\'", query)
- values = str_1 + str_2
- """
-
- toks = sqlparse.parse(query)[0].flatten()
- values = [
- t.value
- for t in toks
- if t.ttype == sqlparse.tokens.Literal.String.Single
- or t.ttype == sqlparse.tokens.Literal.String.Symbol
- ]
-
- for val in values:
- all_values.append(val)
- query = query.replace(val.strip(), VALUE_NUM_SYMBOL)
-
- query_tokenized = query.split()
- float_nums = re.findall("[-+]?\d*\.\d+", query)
- all_values += [qt for qt in query_tokenized if qt in float_nums]
- query_tokenized = [
- VALUE_NUM_SYMBOL if qt in float_nums else qt for qt in query_tokenized
- ]
-
- query = " ".join(query_tokenized)
- int_nums = [i.strip() for i in re.findall("[^tT]\d+", query)]
-
- all_values += [qt for qt in query_tokenized if qt in int_nums]
- query_tokenized = [
- VALUE_NUM_SYMBOL if qt in int_nums else qt for qt in query_tokenized
- ]
- # print int_nums, query, query_tokenized
-
- for tok in query_tokenized:
- if "." in tok:
- table = re.findall("[Tt]\d+\.", tok)
- if len(table) > 0:
- to = tok.replace(".", " . ").split()
- to = [t.lower() for t in to if len(t) > 0]
- query_keywords.extend(to)
- else:
- query_keywords.append(tok.lower())
-
- elif len(tok) > 0:
- query_keywords.append(tok.lower())
- return query_keywords, all_values
-
-
-def reformat_query(query: str) -> str:
- query = query.strip().replace(";", "").replace("\t", "")
- query = " ".join(
- [t.value for t in tokenize(query) if t.ttype != sqlparse.tokens.Whitespace]
- )
- t_stars = ["t1.*", "t2.*", "t3.*", "T1.*", "T2.*", "T3.*"]
- for ts in t_stars:
- query = query.replace(ts, "*")
- return query
-
-
-def replace_values(sql: str) -> Tuple[List[str], Set[str]]:
- sql = sqlparse.format(sql, reindent=False, keyword_case="upper")
- # sql = re.sub(r"(<=|>=|!=|=|<|>|,)", r" \1 ", sql)
- sql = re.sub(r"(T\d+\.)\s", r"\1", sql)
- query_toks_no_value, values = strip_query(sql)
- return query_toks_no_value, set(values)
-
-
-# extract the non-value tokens and the set of values
-# from a sql query
-def extract_query_values(sql: str) -> Tuple[List[str], Set[str]]:
- reformated = reformat_query(query=sql)
- query_value_replaced, values = replace_values(reformated)
- return query_value_replaced, values
-
-
-# given the gold query and the model prediction
-# extract values from the gold, extract predicted sql with value slots
-# return 1) number of possible ways to plug in gold values and 2) an iterator of predictions with value plugged in
-def get_all_preds_for_execution(gold: str, pred: str) -> Tuple[int, Iterator[str]]:
- _, gold_values = extract_query_values(gold)
- pred_query_value_replaced, _ = extract_query_values(pred)
- num_slots = len(
- [v for v in pred_query_value_replaced if v == VALUE_NUM_SYMBOL.lower()]
- )
- num_alternatives = len(gold_values) ** num_slots
- return num_alternatives, plugin_all_permutations(
- pred_query_value_replaced, gold_values
- )
-
-
-def remove_distinct(s):
- toks = [t.value for t in list(sqlparse.parse(s)[0].flatten())]
- return "".join([t for t in toks if t.lower() != "distinct"])
-
-
-# postprocess the model predictions to avoid execution errors
-# e.g. removing spaces between ">" and "="
-def postprocess(query: str) -> str:
- query = query.replace("> =", ">=").replace("< =", "<=").replace("! =", "!=")
- return query
-
-
-def replace_cur_year(query: str) -> str:
- return re.sub(
- "YEAR\s*\(\s*CURDATE\s*\(\s*\)\s*\)\s*", "2020", query, flags=re.IGNORECASE
- )
-
-
-# get the database cursor for a sqlite database path
-def get_cursor_from_path(sqlite_path: str):
- try:
- if not os.path.exists(sqlite_path):
- print("Openning a new connection %s" % sqlite_path)
- connection = sqlite3.connect(sqlite_path)
- except Exception as e:
- print(sqlite_path)
- raise e
- connection.text_factory = lambda b: b.decode(errors="ignore")
- cursor = connection.cursor()
- return cursor
-
-
-async def exec_on_db_(sqlite_path: str, query: str) -> Tuple[str, Any]:
- query = replace_cur_year(query)
- cursor = get_cursor_from_path(sqlite_path)
- try:
- cursor.execute(query)
- result = cursor.fetchall()
- cursor.close()
- cursor.connection.close()
- return "result", result
- except Exception as e:
- cursor.close()
- cursor.connection.close()
- return "exception", e
-
-
-TIMEOUT = 60
-
-
-async def exec_on_db(
- sqlite_path: str, query: str, process_id: str = "", timeout: int = TIMEOUT
-) -> Tuple[str, Any]:
- try:
- return await asyncio.wait_for(exec_on_db_(sqlite_path, query), timeout)
- except asyncio.TimeoutError:
- return ("exception", TimeoutError)
- except Exception as e:
- return ("exception", e)
-
-
-def permute_tuple(element: Tuple, perm: Tuple) -> Tuple:
- assert len(element) == len(perm)
- return tuple([element[i] for i in perm])
-
-
-def unorder_row(row: Tuple) -> Tuple:
- return tuple(sorted(row, key=lambda x: str(x) + str(type(x))))
-
-
-# unorder each row in the table
-# [result_1 and result_2 has the same bag of unordered row]
-# is a necessary condition of
-# [result_1 and result_2 are equivalent in denotation]
-def quick_rej(result1: List[Tuple], result2: List[Tuple], order_matters: bool) -> bool:
- s1 = [unorder_row(row) for row in result1]
- s2 = [unorder_row(row) for row in result2]
- if order_matters:
- return s1 == s2
- else:
- return set(s1) == set(s2)
-
-
-def get_constraint_permutation(tab1_sets_by_columns: List[Set], result2: List[Tuple]):
- num_cols = len(result2[0])
- perm_constraints = [{i for i in range(num_cols)} for _ in range(num_cols)]
- if num_cols <= 3:
- return product(*perm_constraints)
-
- # we sample 20 rows and constrain the space of permutations
- for _ in range(20):
- random_tab2_row = random.choice(result2)
-
- for tab1_col in range(num_cols):
- for tab2_col in set(perm_constraints[tab1_col]):
- if random_tab2_row[tab2_col] not in tab1_sets_by_columns[tab1_col]:
- perm_constraints[tab1_col].remove(tab2_col)
- return product(*perm_constraints)
-
-
-# return whether two bag of relations are equivalent
-def multiset_eq(l1: List, l2: List) -> bool:
- if len(l1) != len(l2):
- return False
- d = defaultdict(int)
- for e in l1:
- d[e] = d[e] + 1
- for e in l2:
- d[e] = d[e] - 1
- if d[e] < 0:
- return False
- return True
-
-
-# check whether two denotations are correct
-def result_eq(result1: List[Tuple], result2: List[Tuple], order_matters: bool) -> bool:
- if len(result1) == 0 and len(result2) == 0:
- return True
-
- # if length is not the same, then they are definitely different bag of rows
- if len(result1) != len(result2):
- return False
-
- num_cols = len(result1[0])
-
- # if the results do not have the same number of columns, they are different
- if len(result2[0]) != num_cols:
- return False
-
- # unorder each row and compare whether the denotation is the same
- # this can already find most pair of denotations that are different
- if not quick_rej(result1, result2, order_matters):
- return False
-
- # the rest of the problem is in fact more complicated than one might think
- # we want to find a permutation of column order and a permutation of row order,
- # s.t. result_1 is the same as result_2
- # we return true if we can find such column & row permutations
- # and false if we cannot
- tab1_sets_by_columns = [{row[i] for row in result1} for i in range(num_cols)]
-
- # on a high level, we enumerate all possible column permutations that might make result_1 == result_2
- # we decrease the size of the column permutation space by the function get_constraint_permutation
- # if one of the permutation make result_1, result_2 equivalent, then they are equivalent
- for perm in get_constraint_permutation(tab1_sets_by_columns, result2):
- if len(perm) != len(set(perm)):
- continue
- if num_cols == 1:
- result2_perm = result2
- else:
- result2_perm = [permute_tuple(element, perm) for element in result2]
- if order_matters:
- if result1 == result2_perm:
- return True
- else:
- # in fact the first condition must hold if the second condition holds
- # but the first is way more efficient implementation-wise
- # and we use it to quickly reject impossible candidates
- if set(result1) == set(result2_perm) and multiset_eq(result1, result2_perm):
- return True
- return False
-
-
-# approximate whether p_str and g_str are semantically equivalent
-# db is the database path
-# we are going to evaluate whether they are equivalent in all the databases
-# that are in the same directory as db
-# 0 if denotationally equivalent
-# 1 otherwise
-# the meaning of each auxillary argument can be seen in the parser definition in evaluation.py
-async def eval_exec_match(
- db: str,
- p_str: str,
- g_str: str,
- plug_value: bool = False,
- keep_distinct: bool = False,
- progress_bar_for_each_datapoint: bool = False,
-) -> int:
- # post-process the prediction.
- # e.g. removing spaces between ">" and "="
- p_str, g_str = postprocess(p_str), postprocess(g_str)
- if not keep_distinct:
- p_str = remove_distinct(p_str)
- g_str = remove_distinct(g_str)
-
- # we decide whether two denotations are equivalent based on "bag semantics"
- # https://courses.cs.washington.edu/courses/cse444/10sp/lectures/lecture16.pdf
- # if there is order by in query, then we assume order of the rows matter
- # order by might also be used to find the max/min instead of sorting,
- # but in that case the result mostly only contains one row and hence order_matters does not make a difference
- order_matters = "order by" in g_str.lower()
-
- # find all databases in the same directory
- db_dir = os.path.dirname(db)
- db_paths = [
- os.path.join(db_dir, basename)
- for basename in os.listdir(db_dir)
- if ".sqlite" in basename
- ]
-
- preds = [p_str]
- # if plug in value (i.e. we do not consider value prediction correctness)
- # enumerate all ways to plug in values in the gold query to the model predictions
- # otherwise, we only evaluate the predicted query with its own value prediction
- if plug_value:
- _, preds = get_all_preds_for_execution(g_str, p_str)
- # we did not add this line in our EMNLP work
- # this reduces "false negatives" when value is substituted
- preds = chain([p_str], preds)
-
- for pred in preds:
- pred_passes = 1
- # compare the gold and predicted denotations on each database in the directory
- # wrap with progress bar if required
- if progress_bar_for_each_datapoint:
- ranger = tqdm.tqdm(db_paths)
- else:
- ranger = db_paths
-
- for db_path in ranger:
- g_flag, g_denotation = await exec_on_db(db_path, g_str)
- p_flag, p_denotation = await exec_on_db(db_path, pred)
-
- # we should expect the gold to be succesfully executed on the database
- assert g_flag != "exception", (
- "gold query %s has error on database file %s" % (g_str, db_path)
- )
-
- # wrong if execution fails
- if p_flag == "exception":
- pred_passes = 0
-
- # if denotations are not equivalent, the prediction must be wrong
- elif not result_eq(g_denotation, p_denotation, order_matters=order_matters):
- pred_passes = 0
- if pred_passes == 0:
- break
-
- # the model prediction has the same denotation as the gold for all databases
- if pred_passes == 1:
- return 1
-
- # none of the predictions passed
- return 0
diff --git a/wren-ai-service/eval/metrics/spider/exact_match.py b/wren-ai-service/eval/metrics/spider/exact_match.py
deleted file mode 100644
index a6d61434c..000000000
--- a/wren-ai-service/eval/metrics/spider/exact_match.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import asyncio
-import os
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-from eval.metrics.spider import Evaluator, build_foreign_key_map_from_json, tokenize
-from eval.metrics.spider.process_sql import Schema, get_schema
-
-
-class ExactMatchAccuracy(BaseMetric):
- def __init__(
- self,
- kmap_path: str = "./tools/dev/etc/spider1.0/spider_data/tables.json",
- db_dir: str = "./tools/dev/etc/spider1.0/database",
- ):
- self.threshold = 0
- self.score = 0
- self.kmaps = build_foreign_key_map_from_json(kmap_path)
-
- self.db_dir = db_dir
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- if not test_case.additional_metadata["enable_spider_metrics"]:
- self.success = True
- return 0
-
- db_name = test_case.additional_metadata["catalog"]
- db = os.path.join(self.db_dir, db_name, db_name + ".sqlite")
- schema = Schema(get_schema(db))
- gold_sql = tokenize(test_case.expected_output, schema, self.kmaps[db_name])
- pred_sql = tokenize(test_case.actual_output, schema, self.kmaps[db_name])
-
- evaluator = Evaluator()
- self.score = evaluator.eval_exact_match(pred_sql, gold_sql)
- self.success = self.score >= self.threshold
-
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ExactMatchAccuracy"
-
-
-if __name__ == "__main__":
- metric = ExactMatchAccuracy()
- test_case = LLMTestCase(
- input="",
- expected_output="SELECT COUNT(DISTINCT Nationality) FROM people",
- actual_output='SELECT COUNT(DISTINCT "Nationality") AS "nationality_count" FROM "people"',
- additional_metadata={"catalog": "poker_player"},
- )
- print(metric.measure(test_case))
diff --git a/wren-ai-service/eval/metrics/spider/exec_match.py b/wren-ai-service/eval/metrics/spider/exec_match.py
deleted file mode 100644
index a00cb77e2..000000000
--- a/wren-ai-service/eval/metrics/spider/exec_match.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import asyncio
-import os
-
-from deepeval.metrics import BaseMetric
-from deepeval.test_case import LLMTestCase
-
-from eval.metrics.spider import eval_exec_match
-
-
-class ExecutionAccuracy(BaseMetric):
- def __init__(
- self,
- db_dir: str = "./tools/dev/etc/spider1.0/database",
- ):
- self.threshold = 0
- self.score = 0
-
- self.db_dir = db_dir
-
- def measure(self, test_case: LLMTestCase):
- return asyncio.run(self.a_measure(test_case))
-
- async def a_measure(self, test_case: LLMTestCase, *args, **kwargs):
- if not test_case.additional_metadata["enable_spider_metrics"]:
- self.success = True
- return 0
-
- db_name = test_case.additional_metadata["catalog"]
- db = os.path.join(self.db_dir, db_name, db_name + ".sqlite")
-
- self.score = await eval_exec_match(
- db=db,
- p_str=test_case.actual_output,
- g_str=test_case.expected_output,
- )
-
- self.success = self.score >= self.threshold
-
- return self.score
-
- def is_successful(self):
- return self.success
-
- @property
- def __name__(self):
- return "ExecutionAccuracy"
-
-
-if __name__ == "__main__":
- metric = ExecutionAccuracy()
- test_case = LLMTestCase(
- input="",
- expected_output="SELECT COUNT(DISTINCT Nationality) FROM people",
- actual_output='SELECT COUNT(DISTINCT "Nationality") AS "nationality_count" FROM "people"',
- additional_metadata={"catalog": "poker_player"},
- )
- print(metric.measure(test_case))
diff --git a/wren-ai-service/eval/metrics/spider/process_sql.py b/wren-ai-service/eval/metrics/spider/process_sql.py
deleted file mode 100644
index 0a0e6beb3..000000000
--- a/wren-ai-service/eval/metrics/spider/process_sql.py
+++ /dev/null
@@ -1,648 +0,0 @@
-################################
-# Assumptions:
-# 1. sql is correct
-# 2. only table name has alias
-# 3. only one intersect/union/except
-#
-# val: number(float)/string(str)/sql(dict)
-# col_unit: (agg_id, col_id, isDistinct(bool))
-# val_unit: (unit_op, col_unit1, col_unit2)
-# table_unit: (table_type, col_unit/sql)
-# cond_unit: (not_op, op_id, val_unit, val1, val2)
-# condition: [cond_unit1, 'and'/'or', cond_unit2, ...]
-# sql {
-# 'select': (isDistinct(bool), [(agg_id, val_unit), (agg_id, val_unit), ...])
-# 'from': {'table_units': [table_unit1, table_unit2, ...], 'conds': condition}
-# 'where': condition
-# 'groupBy': [col_unit1, col_unit2, ...]
-# 'orderBy': ('asc'/'desc', [val_unit1, val_unit2, ...])
-# 'having': condition
-# 'limit': None/limit value
-# 'intersect': None/sql
-# 'except': None/sql
-# 'union': None/sql
-# }
-################################
-
-import json
-import sqlite3
-
-import nltk
-
-nltk.download("punkt_tab")
-
-CLAUSE_KEYWORDS = (
- "select",
- "from",
- "where",
- "group",
- "order",
- "limit",
- "intersect",
- "union",
- "except",
-)
-JOIN_KEYWORDS = ("join", "on", "as")
-
-WHERE_OPS = (
- "not",
- "between",
- "=",
- ">",
- "<",
- ">=",
- "<=",
- "!=",
- "in",
- "like",
- "is",
- "exists",
-)
-UNIT_OPS = ("none", "-", "+", "*", "/")
-AGG_OPS = ("none", "max", "min", "count", "sum", "avg")
-TABLE_TYPE = {
- "sql": "sql",
- "table_unit": "table_unit",
-}
-
-COND_OPS = ("and", "or")
-SQL_OPS = ("intersect", "union", "except")
-ORDER_OPS = ("desc", "asc")
-
-
-class Schema:
- """
- Simple schema which maps table&column to a unique identifier
- """
-
- def __init__(self, schema):
- self._schema = schema
- self._idMap = self._map(self._schema)
-
- @property
- def schema(self):
- return self._schema
-
- @property
- def idMap(self):
- return self._idMap
-
- def _map(self, schema):
- idMap = {"*": "__all__"}
- id = 1
- for key, vals in schema.items():
- for val in vals:
- idMap[key.lower() + "." + val.lower()] = (
- "__" + key.lower() + "." + val.lower() + "__"
- )
- id += 1
-
- for key in schema:
- idMap[key.lower()] = "__" + key.lower() + "__"
- id += 1
-
- return idMap
-
-
-def get_schema(db):
- """
- Get database's schema, which is a dict with table name as key
- and list of column names as value
- :param db: database path
- :return: schema dict
- """
-
- schema = {}
- conn = sqlite3.connect(db)
- cursor = conn.cursor()
-
- # fetch table names
- cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
- tables = [str(table[0].lower()) for table in cursor.fetchall()]
-
- # fetch table info
- for table in tables:
- cursor.execute("PRAGMA table_info({})".format(table))
- schema[table] = [str(col[1].lower()) for col in cursor.fetchall()]
-
- return schema
-
-
-def get_schema_from_json(fpath):
- with open(fpath) as f:
- data = json.load(f)
-
- schema = {}
- for entry in data:
- table = str(entry["table"].lower())
- cols = [str(col["column_name"].lower()) for col in entry["col_data"]]
- schema[table] = cols
-
- return schema
-
-
-def tokenize(string):
- string = str(string)
- string = string.replace(
- "'", '"'
- ) # ensures all string values wrapped by "" problem??
- quote_idxs = [idx for idx, char in enumerate(string) if char == '"']
- assert len(quote_idxs) % 2 == 0, "Unexpected quote"
-
- # keep string value as token
- vals = {}
- for i in range(len(quote_idxs) - 1, -1, -2):
- qidx1 = quote_idxs[i - 1]
- qidx2 = quote_idxs[i]
- val = string[qidx1 : qidx2 + 1]
- key = "__val_{}_{}__".format(qidx1, qidx2)
- string = string[:qidx1] + key + string[qidx2 + 1 :]
- vals[key] = val
-
- toks = [word.lower() for word in nltk.word_tokenize(string)]
- # replace with string value token
- for i in range(len(toks)):
- if toks[i] in vals:
- toks[i] = vals[toks[i]]
-
- # find if there exists !=, >=, <=
- eq_idxs = [idx for idx, tok in enumerate(toks) if tok == "="]
- eq_idxs.reverse()
- prefix = ("!", ">", "<")
- for eq_idx in eq_idxs:
- pre_tok = toks[eq_idx - 1]
- if pre_tok in prefix:
- toks = toks[: eq_idx - 1] + [pre_tok + "="] + toks[eq_idx + 1 :]
-
- return toks
-
-
-def scan_alias(toks):
- """Scan the index of 'as' and build the map for all alias"""
- as_idxs = [idx for idx, tok in enumerate(toks) if tok == "as"]
- alias = {}
- for idx in as_idxs:
- alias[toks[idx + 1]] = toks[idx - 1]
- return alias
-
-
-def get_tables_with_alias(schema, toks):
- tables = scan_alias(toks)
- for key in schema:
- assert key not in tables, "Alias {} has the same name in table".format(key)
- tables[key] = key
- return tables
-
-
-def parse_col(toks, start_idx, tables_with_alias, schema, default_tables=None):
- """
- :returns next idx, column id
- """
- tok = toks[start_idx]
- if tok == "*":
- return start_idx + 1, schema.idMap[tok]
-
- if "." in tok: # if token is a composite
- alias, col = tok.split(".")
- key = tables_with_alias[alias] + "." + col
- return start_idx + 1, schema.idMap[key]
-
- assert (
- default_tables is not None and len(default_tables) > 0
- ), "Default tables should not be None or empty"
-
- for alias in default_tables:
- table = tables_with_alias[alias]
- if tok in schema.schema[table]:
- key = table + "." + tok
- return start_idx + 1, schema.idMap[key]
-
- assert False, "Error col: {}".format(tok)
-
-
-def parse_col_unit(toks, start_idx, tables_with_alias, schema, default_tables=None):
- """
- :returns next idx, (agg_op id, col_id)
- """
- idx = start_idx
- len_ = len(toks)
- isBlock = False
- isDistinct = False
- if toks[idx] == "(":
- isBlock = True
- idx += 1
-
- if toks[idx] in AGG_OPS:
- agg_id = AGG_OPS.index(toks[idx])
- idx += 1
- assert idx < len_ and toks[idx] == "("
- idx += 1
- if toks[idx] == "distinct":
- idx += 1
- isDistinct = True
- idx, col_id = parse_col(toks, idx, tables_with_alias, schema, default_tables)
- assert idx < len_ and toks[idx] == ")"
- idx += 1
- return idx, (agg_id, col_id, isDistinct)
-
- if toks[idx] == "distinct":
- idx += 1
- isDistinct = True
- agg_id = AGG_OPS.index("none")
- idx, col_id = parse_col(toks, idx, tables_with_alias, schema, default_tables)
-
- if isBlock:
- assert toks[idx] == ")"
- idx += 1 # skip ')'
-
- return idx, (agg_id, col_id, isDistinct)
-
-
-def parse_val_unit(toks, start_idx, tables_with_alias, schema, default_tables=None):
- idx = start_idx
- len_ = len(toks)
- isBlock = False
- if toks[idx] == "(":
- isBlock = True
- idx += 1
-
- col_unit1 = None
- col_unit2 = None
- unit_op = UNIT_OPS.index("none")
-
- idx, col_unit1 = parse_col_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
- if idx < len_ and toks[idx] in UNIT_OPS:
- unit_op = UNIT_OPS.index(toks[idx])
- idx += 1
- idx, col_unit2 = parse_col_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
-
- if isBlock:
- assert toks[idx] == ")"
- idx += 1 # skip ')'
-
- return idx, (unit_op, col_unit1, col_unit2)
-
-
-def parse_table_unit(toks, start_idx, tables_with_alias, schema):
- """
- :returns next idx, table id, table name
- """
- idx = start_idx
- len_ = len(toks)
- key = tables_with_alias[toks[idx]]
-
- if idx + 1 < len_ and toks[idx + 1] == "as":
- idx += 3
- else:
- idx += 1
-
- return idx, schema.idMap[key], key
-
-
-def parse_value(toks, start_idx, tables_with_alias, schema, default_tables=None):
- idx = start_idx
- len_ = len(toks)
-
- isBlock = False
- if toks[idx] == "(":
- isBlock = True
- idx += 1
-
- if toks[idx] == "select":
- idx, val = parse_sql(toks, idx, tables_with_alias, schema)
- elif '"' in toks[idx]: # token is a string value
- val = toks[idx]
- idx += 1
- else:
- try:
- val = float(toks[idx])
- idx += 1
- except ValueError:
- end_idx = idx
- while (
- end_idx < len_
- and toks[end_idx] != ","
- and toks[end_idx] != ")"
- and toks[end_idx] != "and"
- and toks[end_idx] not in CLAUSE_KEYWORDS
- and toks[end_idx] not in JOIN_KEYWORDS
- ):
- end_idx += 1
-
- idx, val = parse_col_unit(
- toks[start_idx:end_idx], 0, tables_with_alias, schema, default_tables
- )
- idx = end_idx
-
- if isBlock:
- assert toks[idx] == ")"
- idx += 1
-
- return idx, val
-
-
-def parse_condition(toks, start_idx, tables_with_alias, schema, default_tables=None):
- idx = start_idx
- len_ = len(toks)
- conds = []
-
- while idx < len_:
- idx, val_unit = parse_val_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
- not_op = False
- if toks[idx] == "not":
- not_op = True
- idx += 1
-
- assert (
- idx < len_ and toks[idx] in WHERE_OPS
- ), "Error condition: idx: {}, tok: {}".format(idx, toks[idx])
- op_id = WHERE_OPS.index(toks[idx])
- idx += 1
- val1 = val2 = None
- if op_id == WHERE_OPS.index(
- "between"
- ): # between..and... special case: dual values
- idx, val1 = parse_value(
- toks, idx, tables_with_alias, schema, default_tables
- )
- assert toks[idx] == "and"
- idx += 1
- idx, val2 = parse_value(
- toks, idx, tables_with_alias, schema, default_tables
- )
- else: # normal case: single value
- idx, val1 = parse_value(
- toks, idx, tables_with_alias, schema, default_tables
- )
- val2 = None
-
- conds.append((not_op, op_id, val_unit, val1, val2))
-
- if idx < len_ and (
- toks[idx] in CLAUSE_KEYWORDS
- or toks[idx] in (")", ";")
- or toks[idx] in JOIN_KEYWORDS
- ):
- break
-
- if idx < len_ and toks[idx] in COND_OPS:
- conds.append(toks[idx])
- idx += 1 # skip and/or
-
- return idx, conds
-
-
-def parse_select(toks, start_idx, tables_with_alias, schema, default_tables=None):
- idx = start_idx
- len_ = len(toks)
-
- assert toks[idx] == "select", "'select' not found"
- idx += 1
- isDistinct = False
- if idx < len_ and toks[idx] == "distinct":
- idx += 1
- isDistinct = True
- val_units = []
-
- while idx < len_ and toks[idx] not in CLAUSE_KEYWORDS:
- agg_id = AGG_OPS.index("none")
- if toks[idx] in AGG_OPS:
- agg_id = AGG_OPS.index(toks[idx])
- idx += 1
- idx, val_unit = parse_val_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
- val_units.append((agg_id, val_unit))
- if idx < len_ and toks[idx] == ",":
- idx += 1 # skip ','
-
- return idx, (isDistinct, val_units)
-
-
-def parse_from(toks, start_idx, tables_with_alias, schema):
- """
- Assume in the from clause, all table units are combined with join
- """
- assert "from" in toks[start_idx:], "'from' not found"
-
- len_ = len(toks)
- idx = toks.index("from", start_idx) + 1
- default_tables = []
- table_units = []
- conds = []
-
- while idx < len_:
- isBlock = False
- if toks[idx] == "(":
- isBlock = True
- idx += 1
-
- if toks[idx] == "select":
- idx, sql = parse_sql(toks, idx, tables_with_alias, schema)
- table_units.append((TABLE_TYPE["sql"], sql))
- else:
- if idx < len_ and toks[idx] == "join":
- idx += 1 # skip join
- idx, table_unit, table_name = parse_table_unit(
- toks, idx, tables_with_alias, schema
- )
- table_units.append((TABLE_TYPE["table_unit"], table_unit))
- default_tables.append(table_name)
- if idx < len_ and toks[idx] == "on":
- idx += 1 # skip on
- idx, this_conds = parse_condition(
- toks, idx, tables_with_alias, schema, default_tables
- )
- if len(conds) > 0:
- conds.append("and")
- conds.extend(this_conds)
-
- if isBlock:
- assert toks[idx] == ")"
- idx += 1
- if idx < len_ and (toks[idx] in CLAUSE_KEYWORDS or toks[idx] in (")", ";")):
- break
-
- return idx, table_units, conds, default_tables
-
-
-def parse_where(toks, start_idx, tables_with_alias, schema, default_tables):
- idx = start_idx
- len_ = len(toks)
-
- if idx >= len_ or toks[idx] != "where":
- return idx, []
-
- idx += 1
- idx, conds = parse_condition(toks, idx, tables_with_alias, schema, default_tables)
- return idx, conds
-
-
-def parse_group_by(toks, start_idx, tables_with_alias, schema, default_tables):
- idx = start_idx
- len_ = len(toks)
- col_units = []
-
- if idx >= len_ or toks[idx] != "group":
- return idx, col_units
-
- idx += 1
- assert toks[idx] == "by"
- idx += 1
-
- while idx < len_ and not (toks[idx] in CLAUSE_KEYWORDS or toks[idx] in (")", ";")):
- idx, col_unit = parse_col_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
- col_units.append(col_unit)
- if idx < len_ and toks[idx] == ",":
- idx += 1 # skip ','
- else:
- break
-
- return idx, col_units
-
-
-def parse_order_by(toks, start_idx, tables_with_alias, schema, default_tables):
- idx = start_idx
- len_ = len(toks)
- val_units = []
- order_type = "asc" # default type is 'asc'
-
- if idx >= len_ or toks[idx] != "order":
- return idx, val_units
-
- idx += 1
- assert toks[idx] == "by"
- idx += 1
-
- while idx < len_ and not (toks[idx] in CLAUSE_KEYWORDS or toks[idx] in (")", ";")):
- idx, val_unit = parse_val_unit(
- toks, idx, tables_with_alias, schema, default_tables
- )
- val_units.append(val_unit)
- if idx < len_ and toks[idx] in ORDER_OPS:
- order_type = toks[idx]
- idx += 1
- if idx < len_ and toks[idx] == ",":
- idx += 1 # skip ','
- else:
- break
-
- return idx, (order_type, val_units)
-
-
-def parse_having(toks, start_idx, tables_with_alias, schema, default_tables):
- idx = start_idx
- len_ = len(toks)
-
- if idx >= len_ or toks[idx] != "having":
- return idx, []
-
- idx += 1
- idx, conds = parse_condition(toks, idx, tables_with_alias, schema, default_tables)
- return idx, conds
-
-
-def parse_limit(toks, start_idx):
- idx = start_idx
- len_ = len(toks)
-
- if idx < len_ and toks[idx] == "limit":
- idx += 2
- # make limit value can work, cannot assume put 1 as a fake limit number
- limit_token = toks[idx - 1]
- if not str(limit_token).isdigit():
- # Preserve previous behaviour but make the intent explicit
- return idx, 1
-
- return idx, int(limit_token)
-
- return idx, None
-
-
-def parse_sql(toks, start_idx, tables_with_alias, schema):
- isBlock = False # indicate whether this is a block of sql/sub-sql
- len_ = len(toks)
- idx = start_idx
-
- sql = {}
- if toks[idx] == "(":
- isBlock = True
- idx += 1
-
- # parse from clause in order to get default tables
- from_end_idx, table_units, conds, default_tables = parse_from(
- toks, start_idx, tables_with_alias, schema
- )
- sql["from"] = {"table_units": table_units, "conds": conds}
- # select clause
- _, select_col_units = parse_select(
- toks, idx, tables_with_alias, schema, default_tables
- )
- idx = from_end_idx
- sql["select"] = select_col_units
- # where clause
- idx, where_conds = parse_where(toks, idx, tables_with_alias, schema, default_tables)
- sql["where"] = where_conds
- # group by clause
- idx, group_col_units = parse_group_by(
- toks, idx, tables_with_alias, schema, default_tables
- )
- sql["groupBy"] = group_col_units
- # having clause
- idx, having_conds = parse_having(
- toks, idx, tables_with_alias, schema, default_tables
- )
- sql["having"] = having_conds
- # order by clause
- idx, order_col_units = parse_order_by(
- toks, idx, tables_with_alias, schema, default_tables
- )
- sql["orderBy"] = order_col_units
- # limit clause
- idx, limit_val = parse_limit(toks, idx)
- sql["limit"] = limit_val
-
- idx = skip_semicolon(toks, idx)
- if isBlock:
- assert toks[idx] == ")"
- idx += 1 # skip ')'
- idx = skip_semicolon(toks, idx)
-
- # intersect/union/except clause
- for op in SQL_OPS: # initialize IUE
- sql[op] = None
- if idx < len_ and toks[idx] in SQL_OPS:
- sql_op = toks[idx]
- idx += 1
- idx, IUE_sql = parse_sql(toks, idx, tables_with_alias, schema)
- sql[sql_op] = IUE_sql
- return idx, sql
-
-
-def load_data(fpath):
- with open(fpath) as f:
- data = json.load(f)
- return data
-
-
-def get_sql(schema, query):
- toks = tokenize(query)
- tables_with_alias = get_tables_with_alias(schema.schema, toks)
- _, sql = parse_sql(toks, 0, tables_with_alias, schema)
-
- return sql
-
-
-def skip_semicolon(toks, start_idx):
- idx = start_idx
- while idx < len(toks) and toks[idx] == ";":
- idx += 1
- return idx
diff --git a/wren-ai-service/eval/optimized/.gitignore b/wren-ai-service/eval/optimized/.gitignore
deleted file mode 100644
index a6c57f5fb..000000000
--- a/wren-ai-service/eval/optimized/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.json
diff --git a/wren-ai-service/eval/pipelines.py b/wren-ai-service/eval/pipelines.py
deleted file mode 100644
index c8c673802..000000000
--- a/wren-ai-service/eval/pipelines.py
+++ /dev/null
@@ -1,491 +0,0 @@
-import asyncio
-import re
-import sys
-from abc import abstractmethod
-from datetime import datetime
-from pathlib import Path
-from typing import Any, Dict, List, Literal
-
-import orjson
-from haystack import Document
-from langfuse.decorators import langfuse_context, observe
-from tqdm.asyncio import tqdm_asyncio
-
-from src.core.pipeline import PipelineComponent
-
-sys.path.append(f"{Path().parent.resolve()}")
-
-from eval import WREN_ENGINE_API_URL, EvalSettings
-from eval.metrics import (
- AccuracyMetric,
- AnswerRelevancyMetric,
- ContextualPrecisionMetric,
- ContextualRecallMetric,
- ContextualRelevancyMetric,
- ExactMatchAccuracy,
- ExecutionAccuracy,
- FaithfulnessMetric,
- QuestionToReasoningJudge,
- ReasoningToSqlJudge,
- SqlSemanticsJudge,
-)
-from eval.utils import (
- engine_config,
- trace_metadata,
-)
-from src.pipelines import generation, indexing, retrieval
-
-
-def deploy_model(mdl: str, pipes: list) -> None:
- async def wrapper():
- tasks = [pipe.run(orjson.dumps(mdl).decode()) for pipe in pipes]
- await asyncio.gather(*tasks)
-
- asyncio.run(wrapper())
-
-
-def extract_units(ddls: list[str]) -> list:
- def parse_ddl(ddl: str) -> list:
- """
- Parses a DDL statement and returns a list of column definitions in the format table_name.column_name, excluding foreign keys.
-
- Args:
- ddl (str): The DDL statement to parse.
-
- Returns:
- list: A list of column definitions in the format table_name.column_name.
- """
- # Regex to extract table name
- table_name_match = re.search(r"CREATE TABLE (\w+)", ddl, re.IGNORECASE)
- table_name = table_name_match.group(1) if table_name_match else None
-
- # Split the DDL into lines
- lines = ddl.splitlines()
- # Define a regex pattern to match foreign key constraints and comments
- foreign_key_pattern = re.compile(r"^\s*FOREIGN KEY", re.IGNORECASE)
- comment_pattern = re.compile(r"^\s*--|/\*|\*/")
-
- # Filter out lines that define foreign keys or are comments
- columns = [
- line.strip()
- for line in lines
- if not foreign_key_pattern.match(line)
- and not comment_pattern.match(line)
- and line.strip()
- ]
-
- # Extract column names and format with table name as prefix
- if table_name:
- columns = [
- f"{table_name}.{line.split()[0]}"
- for line in columns
- if line and line.split()[0] != "CREATE" and line.split()[0] != ");"
- ]
-
- return columns
-
- columns = []
-
- for ddl in ddls:
- columns.extend(parse_ddl(ddl))
-
- return columns
-
-
-class Eval:
- def __init__(self, meta: dict, candidate_size: int = 1, **_):
- self._meta = meta
- self._candidate_size = candidate_size
- self._batch_size = int(meta["batch_size"])
- self._batch_interval = int(meta["batch_interval"])
-
- @property
- def candidate_size(self):
- return self._candidate_size
-
- def predict(self, queries: list) -> List[Dict[str, Any]]:
- def split(queries: list, batch_size: int) -> list[list]:
- return [
- queries[i : i + batch_size] for i in range(0, len(queries), batch_size)
- ]
-
- async def wrapper(batch: list):
- tasks = [self(query) for query in batch]
- results = await tqdm_asyncio.gather(*tasks, desc="Generating Predictions")
- await asyncio.sleep(self._batch_interval)
- return [prediction for predictions in results for prediction in predictions]
-
- batches = [
- asyncio.run(wrapper(batch)) for batch in split(queries, self._batch_size)
- ]
- return [prediction for batch in batches for prediction in batch]
-
- @abstractmethod
- def _process(self, prediction: dict, **_) -> dict:
- ...
-
- @observe(name="Prediction Process", capture_input=False)
- async def process(self, params: dict) -> dict:
- prediction = {
- "trace_id": langfuse_context.get_current_trace_id(),
- "trace_url": langfuse_context.get_current_trace_url(),
- "input": params["question"],
- "actual_output": {},
- "expected_output": params["sql"],
- "retrieval_context": [],
- "context": params["context"],
- "samples": params.get("samples", []),
- "instructions": params.get("instructions", []),
- "type": "execution",
- "reasoning": "",
- "elapsed_time": 0,
- }
-
- langfuse_context.update_current_trace(
- session_id=self._meta.get("session_id"),
- user_id=self._meta.get("user_id"),
- metadata=trace_metadata(self._meta, type=prediction["type"]),
- )
-
- start_time = datetime.now()
- returned = await self._process(prediction, **params)
- returned["elapsed_time"] = (datetime.now() - start_time).total_seconds()
-
- return returned
-
-
-class RetrievalPipeline(Eval):
- def __init__(
- self,
- meta: dict,
- mdl: dict,
- pipe_components: dict,
- settings: EvalSettings,
- **kwargs,
- ):
- super().__init__(meta)
-
- _db_schema_indexing = indexing.DBSchema(
- **pipe_components["db_schema_indexing"],
- column_batch_size=settings.column_indexing_batch_size,
- )
- _table_description_indexing = indexing.TableDescription(
- **pipe_components["table_description_indexing"],
- )
- deploy_model(mdl, [_db_schema_indexing, _table_description_indexing])
-
- self._retrieval = retrieval.DbSchemaRetrieval(
- **pipe_components["db_schema_retrieval"],
- table_retrieval_size=settings.table_retrieval_size,
- table_column_retrieval_size=settings.table_column_retrieval_size,
- )
-
- async def _process(self, params: dict, **_) -> dict:
- result = await self._retrieval.run(query=params["input"])
- documents = result.get("construct_retrieval_results", {}).get(
- "retrieval_results", []
- )
- table_ddls = [document.get("table_ddl") for document in documents]
- params["retrieval_context"] = extract_units(table_ddls)
-
- return params
-
- async def __call__(self, params: dict, **_):
- prediction = await self.process(params)
-
- return [prediction]
-
- @staticmethod
- def metrics(engine_info: dict) -> dict:
- wren_engine_info = engine_info.copy()
- wren_engine_info["api_endpoint"] = WREN_ENGINE_API_URL
-
- return {
- "metrics": [
- ContextualRecallMetric(engine_info=wren_engine_info),
- ContextualRelevancyMetric(),
- ContextualPrecisionMetric(),
- ]
- }
-
-
-class GenerationPipeline(Eval):
- def __init__(
- self,
- meta: dict,
- mdl: dict,
- pipe_components: dict,
- settings: EvalSettings,
- **kwargs,
- ):
- super().__init__(meta)
- self._mdl = mdl
- self._generation = generation.SQLGeneration(
- **pipe_components["sql_generation"],
- )
-
- self._sql_functions_retrieval = retrieval.SqlFunctions(
- **pipe_components["sql_functions_retrieval"],
- )
-
- self._allow_sql_samples = settings.allow_sql_samples
- self._allow_instructions = settings.allow_instructions
- self._allow_sql_functions = settings.allow_sql_functions
- self._engine_info = engine_config(
- mdl, pipe_components, settings.eval_data_db_path
- )
-
- def _get_instructions(self, params: dict) -> list:
- if self._allow_instructions:
- return [
- {"instruction": instruction}
- for instruction in params.get("instructions", [])
- ]
- return []
-
- def _get_samples(self, params: dict) -> list:
- if self._allow_sql_samples:
- return params.get("samples", [])
- return []
-
- async def _process(self, params: dict, document: list, **_) -> dict:
- documents = [Document.from_dict(doc).content for doc in document]
- table_ddls = [document.get("table_ddl") for document in documents]
-
- instructions = self._get_instructions(params)
- samples = self._get_samples(params)
-
- if self._allow_sql_functions:
- sql_functions = await self._sql_functions_retrieval.run()
- else:
- sql_functions = []
-
- actual_output = await self._generation.run(
- query=params["input"],
- contexts=table_ddls,
- sql_samples=samples,
- has_calculated_field=params.get("has_calculated_field", False),
- has_metric=params.get("has_metric", False),
- sql_generation_reasoning=params.get("reasoning", ""),
- instructions=instructions,
- sql_functions=sql_functions,
- )
-
- params["actual_output"] = actual_output
- params["retrieval_context"] = extract_units(table_ddls)
-
- return params
-
- async def __call__(self, params: dict, **_):
- return [await self.process(params)]
-
- @staticmethod
- def metrics(
- engine_info: dict,
- enable_semantics_comparison: bool,
- component: PipelineComponent,
- ) -> dict:
- wren_engine_info = engine_info.copy()
- wren_engine_info["api_endpoint"] = WREN_ENGINE_API_URL
-
- return {
- "metrics": [
- AccuracyMetric(
- engine_info=engine_info,
- enable_semantics_comparison=enable_semantics_comparison,
- ),
- AnswerRelevancyMetric(engine_info=wren_engine_info),
- FaithfulnessMetric(engine_info=wren_engine_info),
- ExactMatchAccuracy(),
- ExecutionAccuracy(),
- QuestionToReasoningJudge(**component),
- ReasoningToSqlJudge(**component),
- SqlSemanticsJudge(**component),
- ],
- "post_metrics": [],
- }
-
-
-class AskPipeline(Eval):
- def __init__(
- self,
- meta: dict,
- mdl: dict,
- pipe_components: dict,
- settings: EvalSettings,
- **kwargs,
- ):
- super().__init__(meta)
-
- _db_schema_indexing = indexing.DBSchema(
- **pipe_components["db_schema_indexing"],
- column_batch_size=settings.column_indexing_batch_size,
- )
- _table_description_indexing = indexing.TableDescription(
- **pipe_components["table_description_indexing"],
- )
- deploy_model(mdl, [_db_schema_indexing, _table_description_indexing])
-
- self._retrieval = retrieval.DbSchemaRetrieval(
- **pipe_components["db_schema_retrieval"],
- table_retrieval_size=settings.table_retrieval_size,
- table_column_retrieval_size=settings.table_column_retrieval_size,
- )
- self._sql_reasoner = generation.SQLGenerationReasoning(
- **pipe_components["sql_generation_reasoning"],
- )
- self._sql_functions_retrieval = retrieval.SqlFunctions(
- **pipe_components["sql_functions_retrieval"],
- )
- self._generation = generation.SQLGeneration(
- **pipe_components["sql_generation"],
- )
- self._allow_sql_samples = settings.allow_sql_samples
- self._allow_instructions = settings.allow_instructions
- self._allow_sql_generation_reasoning = settings.allow_sql_generation_reasoning
- self._allow_sql_functions = settings.allow_sql_functions
- self._engine_info = engine_config(
- mdl, pipe_components, settings.eval_data_db_path
- )
-
- def _get_instructions(self, params: dict) -> list:
- if self._allow_instructions:
- return [
- {"instruction": instruction}
- for instruction in params.get("instructions", [])
- ]
- return []
-
- def _get_samples(self, params: dict) -> list:
- if self._allow_sql_samples:
- return params.get("samples", [])
- return []
-
- async def _process(self, params: dict, **_) -> dict:
- result = await self._retrieval.run(query=params["input"])
- _retrieval_result = result.get("construct_retrieval_results", {})
-
- documents = _retrieval_result.get("retrieval_results", [])
- table_ddls = [document.get("table_ddl") for document in documents]
- has_calculated_field = _retrieval_result.get("has_calculated_field", False)
- has_metric = _retrieval_result.get("has_metric", False)
-
- instructions = self._get_instructions(params)
- samples = self._get_samples(params)
-
- if self._allow_sql_generation_reasoning:
- _reasoning = await self._sql_reasoner.run(
- query=params["input"],
- contexts=documents,
- sql_samples=samples,
- )
- reasoning = _reasoning.get("post_process", {})
- else:
- reasoning = ""
-
- if self._allow_sql_functions:
- sql_functions = await self._sql_functions_retrieval.run()
- else:
- sql_functions = []
-
- actual_output = await self._generation.run(
- query=params["input"],
- contexts=table_ddls,
- sql_samples=samples,
- has_calculated_field=has_calculated_field,
- has_metric=has_metric,
- sql_generation_reasoning=reasoning,
- instructions=instructions,
- sql_functions=sql_functions,
- )
-
- params["actual_output"] = actual_output
- params["retrieval_context"] = extract_units(table_ddls)
- params["has_calculated_field"] = has_calculated_field
- params["has_metric"] = has_metric
- params["reasoning"] = reasoning
-
- return params
-
- async def __call__(self, params: dict, **_):
- return [await self.process(params)]
-
- @staticmethod
- def metrics(
- engine_info: dict,
- enable_semantics_comparison: bool,
- component: PipelineComponent,
- ) -> dict:
- wren_engine_info = engine_info.copy()
- wren_engine_info["api_endpoint"] = WREN_ENGINE_API_URL
-
- return {
- "metrics": [
- AccuracyMetric(
- engine_info=engine_info,
- enable_semantics_comparison=enable_semantics_comparison,
- ),
- AnswerRelevancyMetric(engine_info=wren_engine_info),
- FaithfulnessMetric(engine_info=wren_engine_info),
- ContextualRecallMetric(engine_info=wren_engine_info),
- ContextualRelevancyMetric(),
- ContextualPrecisionMetric(),
- ExactMatchAccuracy(),
- ExecutionAccuracy(),
- QuestionToReasoningJudge(**component),
- ReasoningToSqlJudge(**component),
- SqlSemanticsJudge(**component),
- ],
- "post_metrics": [],
- }
-
-
-def init(
- name: Literal["retrieval", "generation", "ask"],
- meta: dict,
- mdl: dict,
- components: Dict[str, Any],
- settings: EvalSettings,
-) -> Eval:
- args = {
- "meta": meta,
- "mdl": mdl,
- "pipe_components": components,
- "settings": settings,
- }
-
- match name:
- case "retrieval":
- return RetrievalPipeline(**args)
- case "generation":
- return GenerationPipeline(**args)
- case "ask":
- return AskPipeline(**args)
- case _:
- raise ValueError(f"Invalid pipeline name: {name}")
-
-
-def metrics_initiator(
- pipeline: str,
- dataset: dict,
- pipe_components: dict[str, PipelineComponent],
- enable_semantics_comparison: bool = True,
- settings: EvalSettings = EvalSettings(),
-) -> dict:
- engine_info = engine_config(
- dataset["mdl"],
- pipe_components,
- settings.eval_data_db_path,
- )
- component = pipe_components["evaluation"]
- match pipeline:
- case "retrieval":
- return RetrievalPipeline.metrics(engine_info)
- case "generation":
- return GenerationPipeline.metrics(
- engine_info, enable_semantics_comparison, component
- )
- case "ask":
- return AskPipeline.metrics(
- engine_info, enable_semantics_comparison, component
- )
diff --git a/wren-ai-service/eval/prediction.py b/wren-ai-service/eval/prediction.py
deleted file mode 100644
index b640a41f5..000000000
--- a/wren-ai-service/eval/prediction.py
+++ /dev/null
@@ -1,167 +0,0 @@
-import argparse
-import base64
-import sys
-import uuid
-from datetime import datetime
-from pathlib import Path
-from typing import Any, Dict, Tuple
-
-import orjson
-from git import Repo
-from langfuse.decorators import langfuse_context
-from tomlkit import document, dumps
-
-sys.path.append(f"{Path().parent.resolve()}")
-import eval.pipelines as pipelines
-import src.providers as provider
-import src.utils as utils
-from eval import EvalSettings
-from eval.utils import (
- load_eval_data_db_to_postgres,
- parse_db_name,
- parse_toml,
- replace_wren_engine_env_variables,
-)
-
-
-def generate_meta(
- path: str,
- dataset: dict,
- pipe: str,
- settings: EvalSettings,
- **kwargs,
-) -> Dict[str, Any]:
- return {
- "langfuse_url": settings.langfuse_url,
- "user_id": "wren-evaluator", # this property is using for langfuse
- "session_id": f"eval_{pipe}_{uuid.uuid4()}",
- "date": datetime.now(),
- "dataset_id": dataset["dataset_id"],
- "evaluation_dataset": path,
- "query_count": len(dataset["eval_dataset"]),
- "commit": obtain_commit_hash(),
- "column_indexing_batch_size": settings.column_indexing_batch_size,
- "table_retrieval_size": settings.table_retrieval_size,
- "table_column_retrieval_size": settings.table_column_retrieval_size,
- "pipeline": pipe,
- "batch_size": settings.batch_size,
- "batch_interval": settings.batch_interval,
- "catalog": dataset["mdl"]["catalog"],
- "datasource": settings.datasource,
- }
-
-
-def write_prediction(
- meta: dict, predictions: list[dict], dir_path: str = "outputs/predictions"
-) -> None:
- if Path(dir_path).exists() is False:
- Path(dir_path).mkdir(parents=True, exist_ok=True)
-
- output_file = f"prediction_{meta['session_id']}_{meta['date'].strftime('%Y_%m_%d_%H%M%S')}.toml"
- output_path = f"{dir_path}/{output_file}"
-
- doc = document()
- doc.add("meta", meta)
- doc.add("predictions", predictions)
-
- with open(output_path, "w") as file:
- file.write(dumps(doc))
-
- print(f"\n\nPrediction result is saved at {output_path}")
- print(
- f"You can then evaluate the prediction result by running `just eval {output_file}`"
- )
-
-
-def obtain_commit_hash() -> str:
- repo = Repo(search_parent_directories=True)
- branch = repo.active_branch
- return f"{repo.head.commit}@{branch.name}"
-
-
-def parse_args() -> Tuple[str, str]:
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "--file",
- "-F",
- type=str,
- help="Eval dataset file path",
- )
- parser.add_argument(
- "--pipeline",
- "-P",
- type=str,
- choices=["ask", "generation", "retrieval"],
- help="Specify the pipeline that you want to evaluate",
- )
- args = parser.parse_args()
- return args.file, args.pipeline
-
-
-if __name__ == "__main__":
- path, pipe_name = parse_args()
- dataset = parse_toml(path)
-
- settings = EvalSettings()
- # todo: refactor this
- _mdl = base64.b64encode(orjson.dumps(dataset["mdl"])).decode("utf-8")
- if "spider_" in path or "bird_" in path:
- db_name = parse_db_name(path)
- if "spider_" in path:
- settings.eval_data_db_path = "etc/spider1.0/database"
- load_eval_data_db_to_postgres(db_name, settings.eval_data_db_path)
- elif "bird_" in path:
- settings.eval_data_db_path = "etc/bird/minidev/MINIDEV/dev_databases"
- load_eval_data_db_to_postgres(db_name, settings.eval_data_db_path)
-
- settings.datasource = "postgres"
- _connection_info = base64.b64encode(
- orjson.dumps(settings.postgres_info)
- ).decode("utf-8")
- replace_wren_engine_env_variables(
- "wren_ibis",
- {
- "manifest": _mdl,
- "source": settings.datasource,
- "connection_info": _connection_info,
- },
- settings.config_path,
- )
- else:
- _connection_info = base64.b64encode(
- orjson.dumps(settings.bigquery_info)
- ).decode("utf-8")
- replace_wren_engine_env_variables(
- "wren_ibis",
- {
- "manifest": _mdl,
- "source": settings.datasource,
- "connection_info": _connection_info,
- },
- settings.config_path,
- )
-
- pipe_components = provider.generate_components(settings.components)
- utils.init_langfuse(settings)
-
- meta = generate_meta(path=path, dataset=dataset, pipe=pipe_name, settings=settings)
-
- pipe: pipelines.Eval = pipelines.init(
- pipe_name,
- meta,
- mdl=dataset["mdl"],
- components=pipe_components,
- settings=settings,
- )
-
- predictions = pipe.predict(dataset["eval_dataset"])
- meta["expected_batch_size"] = meta["query_count"] * pipe.candidate_size
- meta["actual_batch_size"] = len(predictions)
-
- write_prediction(meta, predictions)
- langfuse_context.flush()
-
- if meta["langfuse_url"]:
- print(
- f"You can also view the prediction result in Langfuse at {meta['langfuse_url']}/sessions/{meta['session_id']}"
- )
diff --git a/wren-ai-service/eval/preparation.py b/wren-ai-service/eval/preparation.py
deleted file mode 100644
index c17647237..000000000
--- a/wren-ai-service/eval/preparation.py
+++ /dev/null
@@ -1,465 +0,0 @@
-"""
-This file aims to prepare spider 1.0 or bird eval dataset for text-to-sql eval purpose
-"""
-
-import argparse
-import asyncio
-import os
-import zipfile
-from collections import defaultdict
-from itertools import zip_longest
-from pathlib import Path
-from urllib.request import urlretrieve
-
-import gdown
-import orjson
-import pandas as pd
-
-from eval import (
- BIRD_DESTINATION_PATH,
- EVAL_DATASET_DESTINATION_PATH,
- SPIDER_DESTINATION_PATH,
- WREN_ENGINE_API_URL,
-)
-from eval.utils import (
- get_contexts_from_sql,
- get_documents_given_contexts,
- get_eval_dataset_in_toml_string,
- get_next_few_items_circular,
-)
-
-
-def download_spider_data(destination_path: Path):
- def _download_and_extract(
- destination_path: Path, path: Path, file_name: str, gdrive_id: str
- ):
- if not (destination_path / path).exists():
- if Path(file_name).exists():
- os.remove(file_name)
-
- url = f"https://drive.google.com/u/0/uc?id={gdrive_id}&export=download"
-
- gdown.download(url, file_name, quiet=False)
-
- with zipfile.ZipFile(file_name, "r") as zip_ref:
- zip_ref.extractall(destination_path)
-
- os.remove(file_name)
-
- _download_and_extract(
- destination_path,
- "database",
- "testsuitedatabases.zip",
- "1mkCx2GOFIqNesD4y8TDAO1yX1QZORP5w",
- )
-
- _download_and_extract(
- destination_path,
- "spider_data",
- "spider_data.zip",
- "1403EGqzIDoHMdQF4c9Bkyl7dZLZ5Wt6J",
- )
-
-
-def download_bird_data(destination_path: Path):
- def _download_and_extract(destination_path: Path, path: Path, file_name: str):
- if not (destination_path / path).exists():
- if Path(file_name).exists():
- os.remove(file_name)
-
- url = "https://bird-bench.oss-cn-beijing.aliyuncs.com/minidev.zip"
-
- print(f"Downloading {file_name} from {url}...")
- urlretrieve(url, file_name)
-
- with zipfile.ZipFile(file_name, "r") as zip_ref:
- zip_ref.extractall(destination_path)
-
- os.remove(file_name)
-
- _download_and_extract(
- destination_path,
- "minidev",
- "minidev.zip",
- )
-
-
-def get_database_names(path: Path):
- return [folder.name for folder in path.iterdir() if folder.is_dir()]
-
-
-def get_tables_by_db(path: Path, key: str):
- with open(path, "rb") as f:
- json_data = orjson.loads(f.read())
-
- return {item[key]: item for item in json_data}
-
-
-def build_mdl_models(database, tables_info, database_info={}):
- def _build_mdl_columns(tables_info, table_index, table_info=None):
- def _merge_column_info(column_names_original, column_types):
- merged_info = []
- for (table_index, column_name), column_type in zip(
- column_names_original, column_types
- ):
- merged_info.append(
- {
- "table_index": table_index,
- "column_name": column_name,
- "column_type": column_type,
- }
- )
- return merged_info
-
- def _get_columns_by_table_index(columns, table_index):
- return list(filter(lambda col: col["table_index"] == table_index, columns))
-
- _columns = _get_columns_by_table_index(
- _merge_column_info(
- tables_info["column_names_original"], tables_info["column_types"]
- ),
- table_index,
- )
-
- columns_info = {}
- if table_info:
- for column_info in table_info:
- original_col_key = next(
- key for key in column_info.keys() if "original_column_name" in key
- )
- if value_description := column_info.get("value_description", ""):
- columns_info[column_info[original_col_key]] = (
- column_info.get("column_description", "")
- + ", "
- + value_description
- ).strip()
- else:
- columns_info[column_info[original_col_key]] = column_info.get(
- "column_description", ""
- ).strip()
-
- # dealing with some edge cases
- return [
- {
- "name": column["column_name"],
- "type": column["column_type"],
- "notNull": False,
- "properties": {
- "description": columns_info.get(column["column_name"], ""),
- }
- if columns_info and columns_info.get(column["column_name"], "")
- else {},
- }
- for column in _columns
- ]
-
- return [
- {
- "name": table,
- "properties": {},
- "tableReference": {
- "catalog": database,
- "schema": "main",
- "table": table,
- },
- "primaryKey": (
- tables_info["column_names_original"][primary_key_column_index][-1]
- if primary_key_column_index
- else ""
- ),
- "columns": _build_mdl_columns(
- tables_info, i, database_info.get(table, None)
- ),
- }
- for i, (table, primary_key_column_index) in enumerate(
- zip_longest(
- tables_info["table_names_original"],
- filter(
- lambda x: isinstance(x, int), tables_info["primary_keys"]
- ), # filter out composite primary keys as of now
- )
- )
- ]
-
-
-def build_mdl_relationships(tables_info):
- relationships = []
- for first, second in tables_info["foreign_keys"]:
- first_table_index, first_column_name = tables_info["column_names_original"][
- first
- ]
- first_foreign_key_table = tables_info["table_names_original"][first_table_index]
-
- second_table_index, second_column_name = tables_info["column_names_original"][
- second
- ]
- second_foreign_key_table = tables_info["table_names_original"][
- second_table_index
- ]
-
- relationships.append(
- {
- "name": f"{first_foreign_key_table}_{first_column_name}_{second_foreign_key_table}_{second_column_name}",
- "models": [first_foreign_key_table, second_foreign_key_table],
- "joinType": "MANY_TO_MANY",
- "condition": f"{first_foreign_key_table}.{first_column_name} = {second_foreign_key_table}.{second_column_name}",
- }
- )
-
- return relationships
-
-
-def get_ground_truths_by_db(path: Path, key: str):
- with open(path, "rb") as f:
- json_data = orjson.loads(f.read())
-
- results = defaultdict(list)
- for item in json_data:
- results[item[key]].append(item)
-
- return results
-
-
-def build_mdl_by_db_using_spider(destination_path: Path):
- # get all database names in the spider testsuite
- database_names = get_database_names(destination_path / "database")
-
- # read tables.json and transform it to be a dictionary with database name as key
- tables_by_db = get_tables_by_db(
- destination_path / "spider_data/tables.json", "db_id"
- )
-
- # build mdl for each database by checking the test_tables.json in spider_data
- mdl_by_db = {}
- for database in database_names:
- if tables_info := tables_by_db.get(database):
- mdl_by_db[database] = {
- "catalog": database,
- "schema": "main",
- "dataSource": "postgres",
- "models": build_mdl_models(database, tables_info),
- "relationships": build_mdl_relationships(tables_info),
- "views": [],
- "metrics": [],
- }
-
- return mdl_by_db
-
-
-def build_question_sql_pairs_by_db_using_spider(destination_path: Path):
- # get all database names in the spider testsuite
- database_names = get_database_names(destination_path / "database")
-
- # get dev.json and transform it to be a dictionary with database name as key
- ground_truths_by_db = get_ground_truths_by_db(
- destination_path / "spider_data/dev.json", "db_id"
- )
-
- question_sql_pairs_by_db = defaultdict(list)
- for database in database_names:
- if ground_truths_info := ground_truths_by_db.get(database):
- for ground_truth in ground_truths_info:
- question_sql_pairs_by_db[database].append(
- {
- "question": ground_truth["question"],
- "sql": ground_truth["query"],
- }
- )
-
- return question_sql_pairs_by_db
-
-
-def build_mdl_by_db_using_bird(destination_path: Path):
- def _get_database_infos(path: Path):
- database_infos = {}
- for folder in path.iterdir():
- if folder.is_dir():
- path_to_database_description = (
- path / folder.name / "database_description"
- )
- if (
- path_to_database_description in folder.iterdir()
- and path_to_database_description.is_dir()
- ):
- database_infos[folder.name] = {}
- for file in path_to_database_description.iterdir():
- if file.is_file() and file.suffix == ".csv":
- df = pd.read_csv(
- file, encoding="ISO-8859-1", keep_default_na=False
- )
- database_infos[folder.name][file.stem] = df.to_dict(
- orient="records"
- )
-
- return database_infos
-
- database_names = get_database_names(
- destination_path / "minidev/MINIDEV/dev_databases"
- )
- database_infos = _get_database_infos(
- destination_path / "minidev/MINIDEV/dev_databases"
- )
- tables_by_db = get_tables_by_db(
- destination_path / "minidev/MINIDEV/dev_tables.json", "db_id"
- )
-
- # build mdl for each database by checking the test_tables.json in spider_data
- mdl_by_db = {}
- for database in database_names:
- if tables_info := tables_by_db.get(database):
- mdl_by_db[database] = {
- "catalog": database,
- "schema": "main",
- "dataSource": "postgres",
- "models": build_mdl_models(
- database, tables_info, database_infos.get(database, {})
- ),
- "relationships": build_mdl_relationships(tables_info),
- "views": [],
- "metrics": [],
- }
-
- return mdl_by_db
-
-
-def build_question_sql_pairs_by_db_using_bird(destination_path: Path):
- database_names = get_database_names(
- destination_path / "minidev/MINIDEV/dev_databases"
- )
-
- ground_truths_by_db = get_ground_truths_by_db(
- destination_path / "minidev/MINIDEV/mini_dev_sqlite.json", "db_id"
- )
-
- question_sql_pairs_by_db = defaultdict(list)
- for database in database_names:
- if ground_truths_info := ground_truths_by_db.get(database):
- for ground_truth in ground_truths_info:
- question_sql_pairs_by_db[database].append(
- {
- "question": ground_truth["question"],
- "sql": ground_truth["SQL"],
- "question_id": ground_truth["question_id"],
- "evidence": ground_truth["evidence"],
- "difficulty": ground_truth["difficulty"],
- }
- )
-
- return question_sql_pairs_by_db
-
-
-def get_mdls_and_question_sql_pairs_by_common_db(mdl_by_db, question_sql_pairs_by_db):
- common_dbs = set(mdl_by_db.keys()) & set(question_sql_pairs_by_db.keys())
-
- return {
- db: {"mdl": mdl_by_db[db], "ground_truth": question_sql_pairs_by_db[db]}
- for db in common_dbs
- }
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(
- description="Prepare evaluation dataset for text-to-sql tasks."
- )
- parser.add_argument(
- "--dataset",
- choices=["spider1.0", "bird"],
- default="spider1.0",
- help="Choose which dataset to prepare (spider1.0 or bird)",
- )
- args = parser.parse_args()
-
- if args.dataset == "spider1.0":
- destination_path = SPIDER_DESTINATION_PATH
- print(
- f"Downloading {args.dataset} data if unavailable in {destination_path}..."
- )
- download_spider_data(destination_path)
- elif args.dataset == "bird":
- destination_path = BIRD_DESTINATION_PATH
- print(
- f"Downloading {args.dataset} data if unavailable in {destination_path}..."
- )
- download_bird_data(destination_path)
-
- print(f"Building mdl and question sql pairs using {args.dataset} data...")
- # get mdl_by_db and question_sql_pairs_by_db whose dbs are present in both dictionaries
- if args.dataset == "spider1.0":
- mdl_and_ground_truths_by_db = get_mdls_and_question_sql_pairs_by_common_db(
- build_mdl_by_db_using_spider(destination_path),
- build_question_sql_pairs_by_db_using_spider(destination_path),
- )
- elif args.dataset == "bird":
- mdl_and_ground_truths_by_db = get_mdls_and_question_sql_pairs_by_common_db(
- build_mdl_by_db_using_bird(destination_path),
- build_question_sql_pairs_by_db_using_bird(destination_path),
- )
-
- print("Creating eval dataset...")
- questions_size = 0
- if args.dataset == "spider1.0":
- eval_data_db_path = "etc/spider1.0/database"
- elif args.dataset == "bird":
- eval_data_db_path = "etc/bird/minidev/MINIDEV/dev_databases"
- for db, values in sorted(mdl_and_ground_truths_by_db.items()):
- candidate_eval_dataset = []
-
- print(f"Database: {db}")
- for i, ground_truth in enumerate(values["ground_truth"]):
- context = asyncio.run(
- get_contexts_from_sql(
- ground_truth["sql"],
- values["mdl"],
- api_endpoint=WREN_ENGINE_API_URL,
- )
- )
-
- # ignore empty context
- if context:
- previous_ground_truths = get_next_few_items_circular(
- values["ground_truth"], i
- )
- sql_pairs = [
- {
- "question": ground_truth["question"],
- "sql": ground_truth["sql"],
- }
- for ground_truth in previous_ground_truths
- ]
-
- instructions = [ground_truth.get("evidence", "")]
-
- candidate_eval_dataset.append(
- {
- "categories": [],
- "question": ground_truth["question"],
- "sql": ground_truth["sql"],
- "context": context,
- "document": get_documents_given_contexts(
- [context], values["mdl"]
- ),
- "samples": sql_pairs,
- "instructions": instructions,
- }
- )
-
- # save eval dataset
- if candidate_eval_dataset:
- if args.dataset == "spider1.0":
- file_name = f"spider_{db}_eval_dataset.toml"
- elif args.dataset == "bird":
- file_name = f"bird_{db}_eval_dataset.toml"
-
- with open(f"{EVAL_DATASET_DESTINATION_PATH}/{file_name}", "w") as f:
- f.write(
- get_eval_dataset_in_toml_string(
- values["mdl"], candidate_eval_dataset
- )
- )
- print(
- f"Successfully creating eval dataset of database {db}, which has {len(candidate_eval_dataset)} questions"
- )
- questions_size += len(candidate_eval_dataset)
- print()
-
- print(f"Total questions size: {questions_size}")
diff --git a/wren-ai-service/eval/utils.py b/wren-ai-service/eval/utils.py
deleted file mode 100644
index c59f88377..000000000
--- a/wren-ai-service/eval/utils.py
+++ /dev/null
@@ -1,621 +0,0 @@
-import base64
-import os
-import re
-import uuid
-from copy import deepcopy
-from datetime import datetime
-from typing import Any, Dict, List, Literal, Optional, get_args
-
-import aiohttp
-import orjson
-import psycopg2
-import requests
-import tomlkit
-import yaml
-from dotenv import load_dotenv
-from openai import AsyncClient
-from tomlkit import parse
-
-import docker
-from eval import WREN_ENGINE_API_URL, EvalSettings
-from src.providers.engine.wren import WrenEngine
-
-load_dotenv(".env", override=True)
-
-
-async def get_data_from_wren_engine(
- sql: str,
- mdl_json: dict,
- api_endpoint: str,
- data_source: Optional[str] = None,
- connection_info: Optional[dict] = None,
- timeout: float = 300,
- limit: Optional[int] = None,
-):
- if data_source == "duckdb":
- async with aiohttp.request(
- "GET",
- f"{api_endpoint}/v1/mdl/preview",
- json={
- "sql": sql,
- "manifest": mdl_json,
- "limit": 500 if limit is None else limit,
- },
- ) as response:
- data = await response.json()
-
- if response.status != 200:
- return {"data": [], "columns": []}
-
- column_names = [col["name"] for col in data["columns"]]
- return {"data": data["data"], "columns": column_names}
- else:
- url = f"{api_endpoint}/v3/connector/{data_source}/query"
- if limit is not None:
- url += f"?limit={limit}"
-
- async with aiohttp.request(
- "POST",
- url,
- json={
- "sql": sql,
- "manifestStr": base64.b64encode(orjson.dumps(mdl_json)).decode(),
- "connectionInfo": connection_info,
- },
- timeout=aiohttp.ClientTimeout(total=timeout),
- ) as response:
- if response.status != 200:
- return {"data": [], "columns": []}
-
- data = await response.json()
- column_names = [col for col in data["columns"]]
-
- return {"data": data["data"], "columns": column_names}
-
-
-async def get_contexts_from_sql(
- sql: str,
- mdl_json: dict,
- api_endpoint: str = WREN_ENGINE_API_URL,
- timeout: float = 300,
- **kwargs,
-) -> list[str]:
- def _get_contexts_from_sql_analysis_results(sql_analysis_results: list[dict]):
- def _compose_contexts_of_select_type(select_items: list[dict]):
- return [
- f"{expr_source['sourceDataset']}.{expr_source['sourceColumn']}"
- for select_item in select_items
- for expr_source in select_item["exprSources"]
- ]
-
- def _compose_contexts_of_filter_type(filter: dict):
- contexts = []
- if filter["type"] == "EXPR":
- contexts += [
- f"{expr_source['sourceDataset']}.{expr_source['sourceColumn']}"
- for expr_source in filter["exprSources"]
- ]
- elif filter["type"] in ("AND", "OR"):
- contexts += _compose_contexts_of_filter_type(filter["left"])
- contexts += _compose_contexts_of_filter_type(filter["right"])
-
- return contexts
-
- def _compose_contexts_of_groupby_type(groupby_keys: list[list[dict]]):
- contexts = []
- for groupby_key_list in groupby_keys:
- contexts += [
- f"{expr_source['sourceDataset']}.{expr_source['sourceColumn']}"
- for groupby_key in groupby_key_list
- for expr_source in groupby_key["exprSources"]
- ]
- return contexts
-
- def _compose_contexts_of_sorting_type(sortings: list[dict]):
- return [
- f"{expr_source['sourceDataset']}.{expr_source['sourceColumn']}"
- for sorting in sortings
- for expr_source in sorting["exprSources"]
- ]
-
- def _compose_contexts_of_relation_type(relation: dict):
- contexts = []
- if relation["type"] != "TABLE" and relation["type"] != "SUBQUERY":
- contexts += [
- f"{expr_source['sourceDataset']}.{expr_source['sourceColumn']}"
- for expr_source in relation["exprSources"]
- ]
-
- contexts += _compose_contexts_of_relation_type(relation["left"])
- contexts += _compose_contexts_of_relation_type(relation["right"])
-
- return contexts
-
- contexts = []
- for result in sql_analysis_results:
- if "selectItems" in result:
- contexts += _compose_contexts_of_select_type(result["selectItems"])
- if "filter" in result:
- contexts += _compose_contexts_of_filter_type(result["filter"])
- if "groupByKeys" in result:
- contexts += _compose_contexts_of_groupby_type(result["groupByKeys"])
- if "sortings" in result:
- contexts += _compose_contexts_of_sorting_type(result["sortings"])
- if "relation" in result:
- contexts += _compose_contexts_of_relation_type(result["relation"])
-
- return sorted(set(contexts))
-
- async def _get_sql_analysis(
- sql: str,
- mdl_json: dict,
- api_endpoint: str,
- timeout: float = 300,
- ) -> List[dict]:
- sql = sql.rstrip(";") if sql.endswith(";") else sql
- manifest_str = base64.b64encode(orjson.dumps(mdl_json)).decode()
-
- async with aiohttp.request(
- "GET",
- f"{api_endpoint}/v2/analysis/sql",
- json={
- "sql": sql,
- "manifestStr": manifest_str,
- },
- timeout=aiohttp.ClientTimeout(total=timeout),
- ) as response:
- return await response.json()
-
- sql_analysis_results = await _get_sql_analysis(
- sql, mdl_json, api_endpoint, timeout=timeout
- )
- contexts = _get_contexts_from_sql_analysis_results(sql_analysis_results)
- return contexts
-
-
-def parse_toml(path: str) -> Dict[str, Any]:
- with open(path) as file:
- return parse(file.read())
-
-
-def parse_db_name(path: str) -> str:
- match = re.search(
- r"bird_(.+?)_eval_dataset\.toml|spider_(.+?)_eval_dataset\.toml", path
- )
- if match:
- return match.group(1) or match.group(2)
- else:
- raise ValueError(
- f"Invalid path format: {path}. Expected format: bird__eval_dataset.toml or spider__eval_dataset.toml"
- )
-
-
-TRACE_TYPES = Literal["execution", "shallow", "summary"]
-
-
-def trace_metadata(
- meta: dict,
- type: TRACE_TYPES,
-) -> dict:
- if type not in get_args(TRACE_TYPES):
- raise ValueError(
- f"Invalid type: {type}, should be one of {get_args(TRACE_TYPES)}"
- )
- return {
- "commit": meta["commit"],
- "dataset_id": meta["dataset_id"],
- "column_indexing_batch_size": meta["column_indexing_batch_size"],
- "table_retrieval_size": meta["table_retrieval_size"],
- "table_column_retrieval_size": meta["table_column_retrieval_size"],
- "type": type,
- "pipeline": meta["pipeline"],
- }
-
-
-def engine_config(
- mdl: dict, pipe_components: dict[str, Any] = {}, path: str = ""
-) -> dict:
- engine = pipe_components.get("sql_generation", {}).get("engine")
-
- if engine is None:
- raise ValueError(
- "SQL Generation engine not found in pipe_components. Ensure 'sql_generation' key exists and contains 'engine' configuration."
- )
-
- if isinstance(engine, WrenEngine):
- print("datasource is duckdb")
- prepare_duckdb_session_sql(engine._endpoint)
- prepare_duckdb_init_sql(engine._endpoint, mdl["catalog"], path)
- return {
- "mdl_json": mdl,
- "api_endpoint": engine._endpoint,
- "timeout": 10,
- "data_source": "duckdb",
- }
-
- return {
- "mdl_json": mdl,
- "data_source": engine._source,
- "api_endpoint": engine._endpoint,
- "connection_info": engine._connection_info,
- "timeout": 10,
- }
-
-
-def get_ddl_commands(mdl: Dict[str, Any]) -> List[str]:
- def _convert_models_and_relationships(
- models: List[Dict[str, Any]], relationships: List[Dict[str, Any]]
- ) -> List[str]:
- ddl_commands = []
-
- # A map to store model primary keys for foreign key relationships
- primary_keys_map = {model["name"]: model["primaryKey"] for model in models}
-
- for model in models:
- table_name = model["name"]
- columns_ddl = []
- for column in model["columns"]:
- if "relationship" not in column:
- if "properties" in column:
- column["properties"]["alias"] = column["properties"].pop(
- "displayName", ""
- )
- comment = f"-- {orjson.dumps(column['properties']).decode('utf-8')}\n "
- else:
- comment = ""
- if "isCalculated" in column and column["isCalculated"]:
- comment = (
- comment
- + f"-- This column is a Calculated Field\n -- column expression: {column['expression']}\n "
- )
- column_name = column["name"]
- column_type = column["type"]
- column_ddl = f"{comment}{column_name} {column_type}"
-
- # If column is a primary key
- if column_name == model.get("primaryKey", ""):
- column_ddl += " PRIMARY KEY"
-
- columns_ddl.append(column_ddl)
-
- # Add foreign key constraints based on relationships
- for relationship in relationships:
- comment = f'-- {{"condition": {relationship["condition"]}, "joinType": {relationship["joinType"]}}}\n '
- if (
- table_name == relationship["models"][0]
- and relationship["joinType"].upper() == "MANY_TO_ONE"
- ):
- related_table = relationship["models"][1]
- fk_column = relationship["condition"].split(" = ")[0].split(".")[1]
- fk_constraint = f"FOREIGN KEY ({fk_column}) REFERENCES {related_table}({primary_keys_map[related_table]})"
- columns_ddl.append(f"{comment}{fk_constraint}")
- elif (
- table_name == relationship["models"][1]
- and relationship["joinType"].upper() == "ONE_TO_MANY"
- ):
- related_table = relationship["models"][0]
- fk_column = relationship["condition"].split(" = ")[1].split(".")[1]
- fk_constraint = f"FOREIGN KEY ({fk_column}) REFERENCES {related_table}({primary_keys_map[related_table]})"
- columns_ddl.append(f"{comment}{fk_constraint}")
- elif (
- table_name in relationship["models"]
- and relationship["joinType"].upper() == "ONE_TO_ONE"
- ):
- index = relationship["models"].index(table_name)
- related_table = [
- m for m in relationship["models"] if m != table_name
- ][0]
- fk_column = (
- relationship["condition"].split(" = ")[index].split(".")[1]
- )
- fk_constraint = f"FOREIGN KEY ({fk_column}) REFERENCES {related_table}({primary_keys_map[related_table]})"
- columns_ddl.append(f"{comment}{fk_constraint}")
-
- if "properties" in model:
- model["properties"]["alias"] = model["properties"].pop(
- "displayName", ""
- )
- comment = (
- f"\n/* {orjson.dumps(model['properties']).decode('utf-8')} */\n"
- )
- else:
- comment = ""
-
- create_table_ddl = (
- f"{comment}CREATE TABLE {table_name} (\n "
- + ",\n ".join(columns_ddl)
- + "\n);"
- )
- ddl_commands.append(create_table_ddl)
-
- return ddl_commands
-
- def _convert_views(views: List[Dict[str, Any]]) -> List[str]:
- def _format(view: Dict[str, Any]) -> str:
- properties = view["properties"] if "properties" in view else ""
- return f"/* {properties} */\nCREATE VIEW {view['name']}\nAS ({view['statement']})"
-
- return [_format(view) for view in views]
-
- def _convert_metrics(metrics: List[Dict[str, Any]]) -> List[str]:
- ddl_commands = []
-
- for metric in metrics:
- table_name = metric["name"]
- columns_ddl = []
- for dimension in metric["dimension"]:
- column_name = dimension["name"]
- column_type = dimension["type"]
- comment = "-- This column is a dimension\n "
- column_ddl = f"{comment}{column_name} {column_type}"
- columns_ddl.append(column_ddl)
-
- for measure in metric["measure"]:
- column_name = measure["name"]
- column_type = measure["type"]
- comment = f"-- This column is a measure\n -- expression: {measure['expression']}\n "
- column_ddl = f"{comment}{column_name} {column_type}"
- columns_ddl.append(column_ddl)
-
- comment = f"\n/* This table is a metric */\n/* Metric Base Object: {metric['baseObject']} */\n"
- create_table_ddl = (
- f"{comment}CREATE TABLE {table_name} (\n "
- + ",\n ".join(columns_ddl)
- + "\n);"
- )
-
- ddl_commands.append(create_table_ddl)
-
- return ddl_commands
-
- semantics = {
- "models": [],
- "relationships": mdl["relationships"],
- "views": mdl["views"],
- "metrics": mdl["metrics"],
- }
-
- for model in mdl["models"]:
- columns = []
- for column in model["columns"]:
- ddl_column = {
- "name": column["name"],
- "type": column["type"],
- }
- if "properties" in column:
- ddl_column["properties"] = column["properties"]
- if "relationship" in column:
- ddl_column["relationship"] = column["relationship"]
- if "expression" in column:
- ddl_column["expression"] = column["expression"]
- if "isCalculated" in column:
- ddl_column["isCalculated"] = column["isCalculated"]
-
- columns.append(ddl_column)
-
- semantics["models"].append(
- {
- "type": "model",
- "name": model["name"],
- "properties": model["properties"] if "properties" in model else {},
- "columns": columns,
- "primaryKey": model["primaryKey"],
- }
- )
-
- return (
- _convert_models_and_relationships(
- semantics["models"], semantics["relationships"]
- )
- + _convert_metrics(semantics["metrics"])
- + _convert_views(semantics["views"])
- )
-
-
-def get_documents_given_contexts(
- contexts_list: list[list[str]], mdl_json: dict
-) -> list[list[dict]]:
- mdl_json_cloned = deepcopy(mdl_json)
-
- def _build_partial_mdl_json(
- contexts_list: list[list[str]], mdl_json: dict
- ) -> list[dict]:
- mdj_json_model_lookup_table = {
- model["name"]: {
- **model,
- "column_lookup": {
- column["name"]: column
- for column in model["columns"]
- if "relationship" not in column
- },
- "relationship_lookup": {
- column["relationship"]: column
- for column in model["columns"]
- if "relationship" in column
- },
- }
- for model in mdl_json["models"]
- }
-
- new_mdl_jsons = []
- for contexts in contexts_list:
- model_candidates = {}
- relationship_candidates = []
- for context in contexts:
- table_name, column_name = context.split(".")
- model = mdj_json_model_lookup_table.get(table_name)
- if model:
- if table_name not in model_candidates:
- model_candidates[table_name] = {
- "name": model["name"],
- "properties": model["properties"],
- "tableReference": model["tableReference"],
- "primaryKey": model["primaryKey"],
- "columns": [],
- }
-
- # add column info
- column = mdj_json_model_lookup_table[table_name]["column_lookup"][
- column_name
- ]
- model_candidates[table_name]["columns"].append(column)
-
- contexts_in_set = set(contexts)
- for relationship in mdl_json["relationships"]:
- relationship_name = relationship["name"]
- condition_str = "".join(
- relationship["condition"].split()
- ) # remove all whitespaces
- conditions = condition_str.split("=")
- if (
- conditions[0] in contexts_in_set
- and conditions[1] in contexts_in_set
- ):
- table_name_first_condition = conditions[0].split(".")[0]
- table_name_second_condition = conditions[1].split(".")[0]
- # add relationship column info
- if (
- relationship_column := mdj_json_model_lookup_table.get(
- table_name_first_condition, {}
- )
- .get("relationship_lookup", {})
- .get(relationship_name, {})
- ):
- model_candidates[table_name_first_condition]["columns"].append(
- relationship_column
- )
- elif (
- relationship_column := mdj_json_model_lookup_table.get(
- table_name_second_condition, {}
- )
- .get("relationship_lookup", {})
- .get(relationship_name, {})
- ):
- model_candidates[table_name_second_condition]["columns"].append(
- relationship_column
- )
-
- # add relationship info
- relationship_candidates.append(relationship)
-
- new_mdl_jsons.append(
- {
- "models": list(model_candidates.values()),
- "relationships": relationship_candidates,
- "views": [],
- "metrics": [],
- }
- )
-
- return new_mdl_jsons
-
- new_mdl_jsons = _build_partial_mdl_json(contexts_list, mdl_json_cloned)
-
- return [
- {
- "id": str(i),
- "meta": {"id": str(i)},
- "content": ddl_command,
- }
- for new_mdl_json in new_mdl_jsons
- for i, ddl_command in enumerate(get_ddl_commands(new_mdl_json))
- ]
-
-
-def get_eval_dataset_in_toml_string(mdl: dict, dataset: list) -> str:
- doc = tomlkit.document()
-
- doc.add("dataset_id", str(uuid.uuid4()))
- doc.add("date", datetime.today().strftime("%Y_%m_%d"))
- doc.add("mdl", mdl)
- doc.add("eval_dataset", dataset)
-
- return tomlkit.dumps(doc, sort_keys=True)
-
-
-def prepare_duckdb_session_sql(api_endpoint: str):
- session_sql = "INSTALL sqlite;"
-
- response = requests.put(
- f"{api_endpoint}/v1/data-source/duckdb/settings/session-sql",
- data=session_sql,
- )
-
- assert response.status_code == 200, response.text
-
-
-def prepare_duckdb_init_sql(api_endpoint: str, db: str, path: str):
- init_sql = f"ATTACH '{path}/{db}/{db}.sqlite' AS {db} (TYPE sqlite);"
-
- response = requests.put(
- f"{api_endpoint}/v1/data-source/duckdb/settings/init-sql",
- data=init_sql,
- )
-
- assert response.status_code == 200, response.text
-
-
-def load_eval_data_db_to_postgres(db: str, path: str):
- abs_path = os.path.abspath(f"tools/dev/{path}")
- postgres_info = EvalSettings().postgres_info
-
- conn = psycopg2.connect(
- host="localhost",
- port=postgres_info["port"],
- database=postgres_info["database"],
- user=postgres_info["user"],
- password=postgres_info["password"],
- )
-
- # delete all tables in the database
- cursor = conn.cursor()
- cursor.execute("DROP SCHEMA IF EXISTS public CASCADE; CREATE SCHEMA public;")
- conn.commit()
- cursor.close()
- conn.close()
-
- # load the eval data db to the postgres
- docker_client = docker.from_env()
- docker_client.containers.run(
- "dimitri/pgloader:latest",
- name="pgloader",
- volumes={abs_path: {"bind": "/data", "mode": "ro"}},
- command=f'pgloader --with "quote identifiers" sqlite:///data/{db}/{db}.sqlite pgsql://{postgres_info["user"]}:{postgres_info["password"]}@{postgres_info["host"]}:{postgres_info["port"]}/{postgres_info["database"]}',
- network="wren_wren",
- remove=True,
- )
-
-
-def get_next_few_items_circular(items: list, i: int, few: int = 5):
- list_length = len(items)
- if list_length < few + 1:
- few = list_length - 1
- return [items[(i + j) % list_length] for j in range(1, few + 1)]
-
-
-def get_openai_client(
- api_key: str = os.getenv("OPENAI_API_KEY"), timeout: float = 60
-) -> AsyncClient:
- return AsyncClient(
- api_key=api_key,
- timeout=timeout,
- )
-
-
-def replace_wren_engine_env_variables(engine_type: str, data: dict, config_path: str):
- assert engine_type in ("wren_engine", "wren_ibis")
-
- with open(config_path, "r") as f:
- configs = list(yaml.safe_load_all(f))
-
- for config in configs:
- if config.get("type") == "engine" and config.get("provider") == engine_type:
- for key, value in data.items():
- config[key] = value
- if "pipes" in config:
- for i, pipe in enumerate(config["pipes"]):
- if "engine" in pipe and pipe["name"] != "sql_functions_retrieval":
- config["pipes"][i]["engine"] = engine_type
-
- with open(config_path, "w") as f:
- yaml.safe_dump_all(configs, f, default_flow_style=False)
diff --git a/wren-ai-service/poetry.lock b/wren-ai-service/poetry.lock
deleted file mode 100644
index a417ec51c..000000000
--- a/wren-ai-service/poetry.lock
+++ /dev/null
@@ -1,7827 +0,0 @@
-# This file is automatically @generated by Poetry 2.3.2 and should not be changed by hand.
-
-[[package]]
-name = "aiodns"
-version = "3.5.0"
-description = "Simple DNS resolver for asyncio"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "aiodns-3.5.0-py3-none-any.whl", hash = "sha256:6d0404f7d5215849233f6ee44854f2bb2481adf71b336b2279016ea5990ca5c5"},
- {file = "aiodns-3.5.0.tar.gz", hash = "sha256:11264edbab51896ecf546c18eb0dd56dff0428c6aa6d2cd87e643e07300eb310"},
-]
-
-[package.dependencies]
-pycares = ">=4.9.0"
-
-[[package]]
-name = "aiohappyeyeballs"
-version = "2.6.1"
-description = "Happy Eyeballs for asyncio"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-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.13.4"
-description = "Async http client/server framework (asyncio)"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "aiohttp-3.13.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6290fe12fe8cefa6ea3c1c5b969d32c010dfe191d4392ff9b599a3f473cbe722"},
- {file = "aiohttp-3.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7520d92c0e8fbbe63f36f20a5762db349ff574ad38ad7bc7732558a650439845"},
- {file = "aiohttp-3.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2710ae1e1b81d0f187883b6e9d66cecf8794b50e91aa1e73fc78bfb5503b5d9"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:717d17347567ded1e273aa09918650dfd6fd06f461549204570c7973537d4123"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:383880f7b8de5ac208fa829c7038d08e66377283b2de9e791b71e06e803153c2"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1867087e2c1963db1216aedf001efe3b129835ed2b05d97d058176a6d08b5726"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6234bf416a38d687c3ab7f79934d7fb2a42117a5b9813aca07de0a5398489023"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3cdd3393130bf6588962441ffd5bde1d3ea2d63a64afa7119b3f3ba349cebbe7"},
- {file = "aiohttp-3.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d0dbc6c76befa76865373d6aa303e480bb8c3486e7763530f7f6e527b471118"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10fb7b53262cf4144a083c9db0d2b4d22823d6708270a9970c4627b248c6064c"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:eb10ce8c03850e77f4d9518961c227be569e12f71525a7e90d17bca04299921d"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7c65738ac5ae32b8feef699a4ed0dc91a0c8618b347781b7461458bbcaaac7eb"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:6b335919ffbaf98df8ff3c74f7a6decb8775882632952fd1810a017e38f15aee"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ec75fc18cb9f4aca51c2cbace20cf6716e36850f44189644d2d69a875d5e0532"},
- {file = "aiohttp-3.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:463fa18a95c5a635d2b8c09babe240f9d7dbf2a2010a6c0b35d8c4dff2a0e819"},
- {file = "aiohttp-3.13.4-cp310-cp310-win32.whl", hash = "sha256:13168f5645d9045522c6cef818f54295376257ed8d02513a37c2ef3046fc7a97"},
- {file = "aiohttp-3.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:a7058af1f53209fdf07745579ced525d38d481650a989b7aa4a3b484b901cdab"},
- {file = "aiohttp-3.13.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8ea0c64d1bcbf201b285c2246c51a0c035ba3bbd306640007bc5844a3b4658c1"},
- {file = "aiohttp-3.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6f742e1fa45c0ed522b00ede565e18f97e4cf8d1883a712ac42d0339dfb0cce7"},
- {file = "aiohttp-3.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dcfb50ee25b3b7a1222a9123be1f9f89e56e67636b561441f0b304e25aaef8f"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3262386c4ff370849863ea93b9ea60fd59c6cf56bf8f93beac625cf4d677c04d"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:473bb5aa4218dd254e9ae4834f20e31f5a0083064ac0136a01a62ddbae2eaa42"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e56423766399b4c77b965f6aaab6c9546617b8994a956821cc507d00b91d978c"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8af249343fafd5ad90366a16d230fc265cf1149f26075dc9fe93cfd7c7173942"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bc0a5cf4f10ef5a2c94fdde488734b582a3a7a000b131263e27c9295bd682d9"},
- {file = "aiohttp-3.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5c7ff1028e3c9fc5123a865ce17df1cb6424d180c503b8517afbe89aa566e6be"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ba5cf98b5dcb9bddd857da6713a503fa6d341043258ca823f0f5ab7ab4a94ee8"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d85965d3ba21ee4999e83e992fecb86c4614d6920e40705501c0a1f80a583c12"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:49f0b18a9b05d79f6f37ddd567695943fcefb834ef480f17a4211987302b2dc7"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7f78cb080c86fbf765920e5f1ef35af3f24ec4314d6675d0a21eaf41f6f2679c"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:67a3ec705534a614b68bbf1c70efa777a21c3da3895d1c44510a41f5a7ae0453"},
- {file = "aiohttp-3.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6630ec917e85c5356b2295744c8a97d40f007f96a1c76bf1928dc2e27465393"},
- {file = "aiohttp-3.13.4-cp311-cp311-win32.whl", hash = "sha256:54049021bc626f53a5394c29e8c444f726ee5a14b6e89e0ad118315b1f90f5e3"},
- {file = "aiohttp-3.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:c033f2bc964156030772d31cbf7e5defea181238ce1f87b9455b786de7d30145"},
- {file = "aiohttp-3.13.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ee62d4471ce86b108b19c3364db4b91180d13fe3510144872d6bad5401957360"},
- {file = "aiohttp-3.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c0fd8f41b54b58636402eb493afd512c23580456f022c1ba2db0f810c959ed0d"},
- {file = "aiohttp-3.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4baa48ce49efd82d6b1a0be12d6a36b35e5594d1dd42f8bfba96ea9f8678b88c"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d738ebab9f71ee652d9dbd0211057690022201b11197f9a7324fd4dba128aa97"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0ce692c3468fa831af7dceed52edf51ac348cebfc8d3feb935927b63bd3e8576"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8e08abcfe752a454d2cb89ff0c08f2d1ecd057ae3e8cc6d84638de853530ebab"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5977f701b3fff36367a11087f30ea73c212e686d41cd363c50c022d48b011d8d"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:54203e10405c06f8b6020bd1e076ae0fe6c194adcee12a5a78af3ffa3c57025e"},
- {file = "aiohttp-3.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:358a6af0145bc4dda037f13167bef3cce54b132087acc4c295c739d05d16b1c3"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:898ea1850656d7d61832ef06aa9846ab3ddb1621b74f46de78fbc5e1a586ba83"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:7bc30cceb710cf6a44e9617e43eebb6e3e43ad855a34da7b4b6a73537d8a6763"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4a31c0c587a8a038f19a4c7e60654a6c899c9de9174593a13e7cc6e15ff271f9"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2062f675f3fe6e06d6113eb74a157fb9df58953ffed0cdb4182554b116545758"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d1ba8afb847ff80626d5e408c1fdc99f942acc877d0702fe137015903a220a9"},
- {file = "aiohttp-3.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b08149419994cdd4d5eecf7fd4bc5986b5a9380285bcd01ab4c0d6bfca47b79d"},
- {file = "aiohttp-3.13.4-cp312-cp312-win32.whl", hash = "sha256:fc432f6a2c4f720180959bc19aa37259651c1a4ed8af8afc84dd41c60f15f791"},
- {file = "aiohttp-3.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:6148c9ae97a3e8bff9a1fc9c757fa164116f86c100468339730e717590a3fb77"},
- {file = "aiohttp-3.13.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:63dd5e5b1e43b8fb1e91b79b7ceba1feba588b317d1edff385084fcc7a0a4538"},
- {file = "aiohttp-3.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:746ac3cc00b5baea424dacddea3ec2c2702f9590de27d837aa67004db1eebc6e"},
- {file = "aiohttp-3.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bda8f16ea99d6a6705e5946732e48487a448be874e54a4f73d514660ff7c05d3"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b061e7b5f840391e3f64d0ddf672973e45c4cfff7a0feea425ea24e51530fc2"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b252e8d5cd66184b570d0d010de742736e8a4fab22c58299772b0c5a466d4b21"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:20af8aad61d1803ff11152a26146d8d81c266aa8c5aa9b4504432abb965c36a0"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:13a5cc924b59859ad2adb1478e31f410a7ed46e92a2a619d6d1dd1a63c1a855e"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:534913dfb0a644d537aebb4123e7d466d94e3be5549205e6a31f72368980a81a"},
- {file = "aiohttp-3.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:320e40192a2dcc1cf4b5576936e9652981ab596bf81eb309535db7e2f5b5672f"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9e587fcfce2bcf06526a43cb705bdee21ac089096f2e271d75de9c339db3100c"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9eb9c2eea7278206b5c6c1441fdd9dc420c278ead3f3b2cc87f9b693698cc500"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:29be00c51972b04bf9d5c8f2d7f7314f48f96070ca40a873a53056e652e805f7"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90c06228a6c3a7c9f776fe4fc0b7ff647fffd3bed93779a6913c804ae00c1073"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a533ec132f05fd9a1d959e7f34184cd7d5e8511584848dab85faefbaac573069"},
- {file = "aiohttp-3.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1c946f10f413836f82ea4cfb90200d2a59578c549f00857e03111cf45ad01ca5"},
- {file = "aiohttp-3.13.4-cp313-cp313-win32.whl", hash = "sha256:48708e2706106da6967eff5908c78ca3943f005ed6bcb75da2a7e4da94ef8c70"},
- {file = "aiohttp-3.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:74a2eb058da44fa3a877a49e2095b591d4913308bb424c418b77beb160c55ce3"},
- {file = "aiohttp-3.13.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:e0a2c961fc92abeff61d6444f2ce6ad35bb982db9fc8ff8a47455beacf454a57"},
- {file = "aiohttp-3.13.4-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:153274535985a0ff2bff1fb6c104ed547cec898a09213d21b0f791a44b14d933"},
- {file = "aiohttp-3.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:351f3171e2458da3d731ce83f9e6b9619e325c45cbd534c7759750cabf453ad7"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f989ac8bc5595ff761a5ccd32bdb0768a117f36dd1504b1c2c074ed5d3f4df9c"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d36fc1709110ec1e87a229b201dd3ddc32aa01e98e7868083a794609b081c349"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42adaeea83cbdf069ab94f5103ce0787c21fb1a0153270da76b59d5578302329"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:92deb95469928cc41fd4b42a95d8012fa6df93f6b1c0a83af0ffbc4a5e218cde"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c0c7c07c4257ef3a1df355f840bc62d133bcdef5c1c5ba75add3c08553e2eed"},
- {file = "aiohttp-3.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f062c45de8a1098cb137a1898819796a2491aec4e637a06b03f149315dff4d8f"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:76093107c531517001114f0ebdb4f46858ce818590363e3e99a4a2280334454a"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:6f6ec32162d293b82f8b63a16edc80769662fbd5ae6fbd4936d3206a2c2cc63b"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5903e2db3d202a00ad9f0ec35a122c005e85d90c9836ab4cda628f01edf425e2"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2d5bea57be7aca98dbbac8da046d99b5557c5cf4e28538c4c786313078aca09e"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:bcf0c9902085976edc0232b75006ef38f89686901249ce14226b6877f88464fb"},
- {file = "aiohttp-3.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3295f98bfeed2e867cab588f2a146a9db37a85e3ae9062abf46ba062bd29165"},
- {file = "aiohttp-3.13.4-cp314-cp314-win32.whl", hash = "sha256:a598a5c5767e1369d8f5b08695cab1d8160040f796c4416af76fd773d229b3c9"},
- {file = "aiohttp-3.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:c555db4bc7a264bead5a7d63d92d41a1122fcd39cc62a4db815f45ad46f9c2c8"},
- {file = "aiohttp-3.13.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45abbbf09a129825d13c18c7d3182fecd46d9da3cfc383756145394013604ac1"},
- {file = "aiohttp-3.13.4-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:74c80b2bc2c2adb7b3d1941b2b60701ee2af8296fc8aad8b8bc48bc25767266c"},
- {file = "aiohttp-3.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c97989ae40a9746650fa196894f317dafc12227c808c774929dda0ff873a5954"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dae86be9811493f9990ef44fff1685f5c1a3192e9061a71a109d527944eed551"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1db491abe852ca2fa6cc48a3341985b0174b3741838e1341b82ac82c8bd9e871"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0e5d701c0aad02a7dce72eef6b93226cf3734330f1a31d69ebbf69f33b86666e"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8ac32a189081ae0a10ba18993f10f338ec94341f0d5df8fff348043962f3c6f8"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:98e968cdaba43e45c73c3f306fca418c8009a957733bac85937c9f9cf3f4de27"},
- {file = "aiohttp-3.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca114790c9144c335d538852612d3e43ea0f075288f4849cf4b05d6cd2238ce7"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ea2e071661ba9cfe11eabbc81ac5376eaeb3061f6e72ec4cc86d7cdd1ffbdbbb"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:34e89912b6c20e0fd80e07fa401fd218a410aa1ce9f1c2f1dad6db1bd0ce0927"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0e217cf9f6a42908c52b46e42c568bd57adc39c9286ced31aaace614b6087965"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:0c296f1221e21ba979f5ac1964c3b78cfde15c5c5f855ffd2caab337e9cd9182"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d99a9d168ebaffb74f36d011750e490085ac418f4db926cce3989c8fe6cb6b1b"},
- {file = "aiohttp-3.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cb19177205d93b881f3f89e6081593676043a6828f59c78c17a0fd6c1fbed2ba"},
- {file = "aiohttp-3.13.4-cp314-cp314t-win32.whl", hash = "sha256:c606aa5656dab6552e52ca368e43869c916338346bfaf6304e15c58fb113ea30"},
- {file = "aiohttp-3.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:014dcc10ec8ab8db681f0d68e939d1e9286a5aa2b993cbbdb0db130853e02144"},
- {file = "aiohttp-3.13.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b3f00bb9403728b08eb3951e982ca0a409c7a871d709684623daeab79465b181"},
- {file = "aiohttp-3.13.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cb15595eb52870f84248d7cc97013a76f52ab02ff74d394be093b1d9b8b82bc0"},
- {file = "aiohttp-3.13.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:907ad36b6a65cff7d88d7aca0f77c650546ba850a4f92c92ecb83590d4613249"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5539ec0d6a3a5c6799b661b7e79166ad1b7ae71ccb59a92fcb6b4ef89295bc94"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3b4e07d8803a70dd886b5f38588e5b49f894995ca8e132b06c31a2583ae2ef6e"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ce7320a945aac4bf0bb8901600e4f9409eb602f25ce3ef4d275b48f6d704a862"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:26ed03f7d3d6453634729e2c7600d7255d65e879559c5a48fe1bb78355cde74b"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3f733916e85506b8000dddc071c6b82f8c68f56c99adb328d6550017db062d"},
- {file = "aiohttp-3.13.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b3d525648fe7c8b4977e460c18098f9f81d7991d72edfdc2f13cf96068f279bc"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4e2e68085730a03704beb2cff035fa8648f62c9f93758d7e6d70add7f7bb5b3b"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:797613182ffaaca0b9ad5f3b3d3ce5d21242c768f75e66c750b8292bd97c9de3"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:2d15e7e4f1099d9e4d863eaf77a8eee5dcb002b7d7188061b0fbee37f845899e"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:19f60011ad60e40a01d242238bb335399e3a4d8df958c63cbb835add8d5c3b5a"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c344c47e85678e410b064fc2ace14db86bb69db7ed5520c234bf13aed603ec30"},
- {file = "aiohttp-3.13.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d904084985ca66459e93797e5e05985c048a9c0633655331144c089943e53d12"},
- {file = "aiohttp-3.13.4-cp39-cp39-win32.whl", hash = "sha256:1746338dc2a33cf706cd7446575d13d451f28f9860bebc908c7632b22e71ae3f"},
- {file = "aiohttp-3.13.4-cp39-cp39-win_amd64.whl", hash = "sha256:a5444dce2e6fba0a1dc2d58d026e674f25f21de178c6f844342629bcef019f2f"},
- {file = "aiohttp-3.13.4.tar.gz", hash = "sha256:d97a6d09c66087890c2ab5d49069e1e570583f7ac0314ecf98294c1b6aaebd38"},
-]
-
-[package.dependencies]
-aiodns = {version = ">=3.3.0", optional = true, markers = "extra == \"speedups\""}
-aiohappyeyeballs = ">=2.5.0"
-aiosignal = ">=1.4.0"
-attrs = ">=17.3.0"
-"backports.zstd" = {version = "*", optional = true, markers = "platform_python_implementation == \"CPython\" and python_version < \"3.14\" and extra == \"speedups\""}
-Brotli = {version = ">=1.2", optional = true, markers = "platform_python_implementation == \"CPython\" and extra == \"speedups\""}
-brotlicffi = {version = ">=1.2", optional = true, markers = "platform_python_implementation != \"CPython\" and extra == \"speedups\""}
-frozenlist = ">=1.1.1"
-multidict = ">=4.5,<7.0"
-propcache = ">=0.2.0"
-yarl = ">=1.17.0,<2.0"
-
-[package.extras]
-speedups = ["Brotli (>=1.2) ; platform_python_implementation == \"CPython\"", "aiodns (>=3.3.0)", "backports.zstd ; platform_python_implementation == \"CPython\" and python_version < \"3.14\"", "brotlicffi (>=1.2) ; platform_python_implementation != \"CPython\""]
-
-[[package]]
-name = "aioresponses"
-version = "0.7.8"
-description = "Mock out requests made by ClientSession from aiohttp package"
-optional = false
-python-versions = "*"
-groups = ["test"]
-files = [
- {file = "aioresponses-0.7.8-py2.py3-none-any.whl", hash = "sha256:b73bd4400d978855e55004b23a3a84cb0f018183bcf066a85ad392800b5b9a94"},
- {file = "aioresponses-0.7.8.tar.gz", hash = "sha256:b861cdfe5dc58f3b8afac7b0a6973d5d7b2cb608dd0f6253d16b8ee8eaf6df11"},
-]
-
-[package.dependencies]
-aiohttp = ">=3.3.0,<4.0.0"
-packaging = ">=22.0"
-
-[[package]]
-name = "aiosignal"
-version = "1.4.0"
-description = "aiosignal: a list of registered asynchronous callbacks"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e"},
- {file = "aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7"},
-]
-
-[package.dependencies]
-frozenlist = ">=1.1.0"
-typing-extensions = {version = ">=4.2", markers = "python_version < \"3.13\""}
-
-[[package]]
-name = "alembic"
-version = "1.17.1"
-description = "A database migration tool for SQLAlchemy."
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "alembic-1.17.1-py3-none-any.whl", hash = "sha256:cbc2386e60f89608bb63f30d2d6cc66c7aaed1fe105bd862828600e5ad167023"},
- {file = "alembic-1.17.1.tar.gz", hash = "sha256:8a289f6778262df31571d29cca4c7fbacd2f0f582ea0816f4c399b6da7528486"},
-]
-
-[package.dependencies]
-Mako = "*"
-SQLAlchemy = ">=1.4.0"
-typing-extensions = ">=4.12"
-
-[package.extras]
-tz = ["tzdata"]
-
-[[package]]
-name = "altair"
-version = "5.5.0"
-description = "Vega-Altair: A declarative statistical visualization library for Python."
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "eval"]
-files = [
- {file = "altair-5.5.0-py3-none-any.whl", hash = "sha256:91a310b926508d560fe0148d02a194f38b824122641ef528113d029fcd129f8c"},
- {file = "altair-5.5.0.tar.gz", hash = "sha256:d960ebe6178c56de3855a68c47b516be38640b73fb3b5111c2a9ca90546dd73d"},
-]
-
-[package.dependencies]
-jinja2 = "*"
-jsonschema = ">=3.0"
-narwhals = ">=1.14.2"
-packaging = "*"
-typing-extensions = {version = ">=4.10.0", markers = "python_version < \"3.14\""}
-
-[package.extras]
-all = ["altair-tiles (>=0.3.0)", "anywidget (>=0.9.0)", "numpy", "pandas (>=1.1.3)", "pyarrow (>=11)", "vega-datasets (>=0.9.0)", "vegafusion[embed] (>=1.6.6)", "vl-convert-python (>=1.7.0)"]
-dev = ["duckdb (>=1.0)", "geopandas", "hatch (>=1.13.0)", "ipython[kernel]", "mistune", "mypy", "pandas (>=1.1.3)", "pandas-stubs", "polars (>=0.20.3)", "pyarrow-stubs", "pytest", "pytest-cov", "pytest-xdist[psutil] (>=3.5,<4.0)", "ruff (>=0.6.0)", "types-jsonschema", "types-setuptools"]
-doc = ["docutils", "jinja2", "myst-parser", "numpydoc", "pillow (>=9,<10)", "pydata-sphinx-theme (>=0.14.1)", "scipy", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinxext-altair"]
-save = ["vl-convert-python (>=1.7.0)"]
-
-[[package]]
-name = "annotated-doc"
-version = "0.0.4"
-description = "Document parameters, class attributes, return types, and variables inline, with Annotated."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320"},
- {file = "annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4"},
-]
-
-[[package]]
-name = "annotated-types"
-version = "0.7.0"
-description = "Reusable constraint types to use with typing.Annotated"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
- {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
-]
-
-[[package]]
-name = "anyio"
-version = "4.11.0"
-description = "High-level concurrency and networking framework on top of asyncio or Trio"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"},
- {file = "anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"},
-]
-
-[package.dependencies]
-idna = ">=2.8"
-sniffio = ">=1.1"
-typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
-
-[package.extras]
-trio = ["trio (>=0.31.0)"]
-
-[[package]]
-name = "appnope"
-version = "0.1.4"
-description = "Disable App Nap on macOS >= 10.9"
-optional = false
-python-versions = ">=3.6"
-groups = ["eval"]
-markers = "platform_system == \"Darwin\""
-files = [
- {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"},
- {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"},
-]
-
-[[package]]
-name = "asttokens"
-version = "3.0.0"
-description = "Annotate AST trees with source code positions"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2"},
- {file = "asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7"},
-]
-
-[package.extras]
-astroid = ["astroid (>=2,<4)"]
-test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"]
-
-[[package]]
-name = "asyncer"
-version = "0.0.8"
-description = "Asyncer, async and await, focused on developer experience."
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "asyncer-0.0.8-py3-none-any.whl", hash = "sha256:5920d48fc99c8f8f0f1576e1882f5022885589c5fcbc46ce4224ec3e53776eeb"},
- {file = "asyncer-0.0.8.tar.gz", hash = "sha256:a589d980f57e20efb07ed91d0dbe67f1d2fd343e7142c66d3a099f05c620739c"},
-]
-
-[package.dependencies]
-anyio = ">=3.4.0,<5.0"
-
-[[package]]
-name = "attrs"
-version = "25.4.0"
-description = "Classes Without Boilerplate"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"},
- {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"},
-]
-
-[[package]]
-name = "backoff"
-version = "2.2.1"
-description = "Function decoration for backoff and retry"
-optional = false
-python-versions = ">=3.7,<4.0"
-groups = ["main", "dev"]
-files = [
- {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"},
- {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"},
-]
-
-[[package]]
-name = "backports-zstd"
-version = "1.0.0"
-description = "Backport of compression.zstd"
-optional = false
-python-versions = "<3.14,>=3.9"
-groups = ["main"]
-markers = "platform_python_implementation == \"CPython\""
-files = [
- {file = "backports_zstd-1.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:34cd28f44f6b8f70ea5d86c2b3ba26d0d51f94606bd1f0c80bde1f820e8c82b2"},
- {file = "backports_zstd-1.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7ccfd860da6b4c0c1f0f68dc917483977383e1207bdee262d40369fe616fc8"},
- {file = "backports_zstd-1.0.0-cp310-cp310-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:65de196c84b0d2c44fb76a729041de3a292f0128ded1b5ff7c1c4eab948aae0b"},
- {file = "backports_zstd-1.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1096d4504557d2deb9e71e1aef9914c651b7aa05c35276d77854fee7a4bdd09a"},
- {file = "backports_zstd-1.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1a0db63d2a112c217a347789aecd38bdd17bc1030fa9d3d256d5d011231852f2"},
- {file = "backports_zstd-1.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0dfab6714325c29d621593b1e9198e47064bb755e601c3e79fde5211a16527f7"},
- {file = "backports_zstd-1.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63076e558ba75b2c016257bdbe6b83b5b9a41fe5b6601b567f1e07890370f2f1"},
- {file = "backports_zstd-1.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cd445dcb1ec8a8aa38d3c4e9cda7991cacead193bb07cf002f60cfc002d8628"},
- {file = "backports_zstd-1.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d01aa1b91007edd00abc78b3cb7e10ad9394b54a75cbd76b1584524a3b238cfc"},
- {file = "backports_zstd-1.0.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d6bbb553640f7ed630223dae9ec93d6f56785d03db0c8385e0c4cfc88d54bdf4"},
- {file = "backports_zstd-1.0.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8d25adbe96f4a3fb6492d8d504e78c1641b06002ca2b578a0b24862ee9fd5a58"},
- {file = "backports_zstd-1.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dde864a9c6aaa94eafe4962f59916de3165e99b3fd4d2f6584cd116707aed8ff"},
- {file = "backports_zstd-1.0.0-cp310-cp310-win32.whl", hash = "sha256:474847d1ac3ed2e4bfca2207bbfd5632110143ddd4fc6ea41ff5c5b05d2fda1d"},
- {file = "backports_zstd-1.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:5d2fb3f4d53b2f92a26e7fc34b313ac5eebd7ff437f37f8f5c308d72c844fbd7"},
- {file = "backports_zstd-1.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:525a1ecb62edd97c6695812fef0e4dc7c2faa5edf3057aa3d8ec9d2dbd0f7799"},
- {file = "backports_zstd-1.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:782923d65aa6d0c8c465c32563df70dbdd3e255532de2a2d26e13598fc5f85ae"},
- {file = "backports_zstd-1.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6825598589ef9b8c0c4e574170d29d84400be24c2f172b81403435b33c8d103a"},
- {file = "backports_zstd-1.0.0-cp311-cp311-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:15863463b7f28049d4511f9f123c3b96d66c3de543315c21ef3bc6b001b20d01"},
- {file = "backports_zstd-1.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b39da619431f4782f3d8bb0d99a6067db571eab50579527ba168bcc12887d328"},
- {file = "backports_zstd-1.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:411da73bb3eadef58da781c55c6399fc6dba9b898ca05009410138fb1d7fef8d"},
- {file = "backports_zstd-1.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1f8b0bc92f5be153a4878188ab0aeab5b9bbff3dc3e9d3ad3b19e29fe4932741"},
- {file = "backports_zstd-1.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cd5bdb76448f2259ea371d6cd62a7e339021e1429fe3c386acb3e58c1f6c61"},
- {file = "backports_zstd-1.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d251a49e80e1868e132e6edadfbef8dba7ded7751e59a41684cd6da38bbd3507"},
- {file = "backports_zstd-1.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a54ea58ddeaab9a1385c368f84fca474b87b052087b62e56ac1ebd10cabac157"},
- {file = "backports_zstd-1.0.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d6272730803dc5b212615f50af7395f2b05155d9415e367492d6dac807edc949"},
- {file = "backports_zstd-1.0.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:f6a27510ebb9e1cb877aaa26fc5e0303437bd2023e0a24976da854a3421e60e5"},
- {file = "backports_zstd-1.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c55f842917ac4405a9779476b1ec8219247f35d86673769cf2d3c140799d3e4a"},
- {file = "backports_zstd-1.0.0-cp311-cp311-win32.whl", hash = "sha256:c28cfbd6217ba4837d35cdd8cfd5dcf84ad54bffcb531734002e27dcc84c87ca"},
- {file = "backports_zstd-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:f009996762b887d1bf9330ac0ce1e83608db0b881f63644ae30f2b6a290cd36b"},
- {file = "backports_zstd-1.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:62ab49843fc7761383aa7bea8105ca70941797c7145647f71fa4340bfd3b747a"},
- {file = "backports_zstd-1.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f9afba11403cf03849464e0f1214b035970d43546a7cdd9d8ee31dc154889e78"},
- {file = "backports_zstd-1.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86498856adc6e8c6f50cbfb1d4afd4e0997d5837fb225245d3fb26008f3c9412"},
- {file = "backports_zstd-1.0.0-cp312-cp312-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:de915a8ecd290c601be7b7436291397b0ac1f7841c97c3a13777bb1065881773"},
- {file = "backports_zstd-1.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fffb08c5c1b629c96813108183c8b02d6b07ed6ec81cca8d094089e749db4b5"},
- {file = "backports_zstd-1.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:064d4dc840bcfd8c5c9b37dcacd4fb27eac473c75006120015a9f88b73368c9b"},
- {file = "backports_zstd-1.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0051911391c3f934bb48e8ca08f4319d94b08362a40d96a4b5534c60f00deca2"},
- {file = "backports_zstd-1.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6e5f3453f0ea32ccf262e11e711ef1a0a986903b8a3a3078bf93fafdd5cf311c"},
- {file = "backports_zstd-1.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:33bce0351cd0ad7bd9f363740b894e65255eb93d16d05097ef1d60643ce1cc27"},
- {file = "backports_zstd-1.0.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:820f3cd08c5c8672015b7e52bf04e3e707727e6576d988eadc1799c0c47b33d9"},
- {file = "backports_zstd-1.0.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4e327fe73bfc634e8b04b5e0f715c97680987d633f161fd4702027b34685be43"},
- {file = "backports_zstd-1.0.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4055318ebb7f6ffad99dabd312706599c9e119c834d6c741a946c0d4b3e5be4e"},
- {file = "backports_zstd-1.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:79d3c879720ee4987782da55d728919f9294a8ea6fac76c9af84bc06f3b0f942"},
- {file = "backports_zstd-1.0.0-cp312-cp312-win32.whl", hash = "sha256:930ccc283fdf76d1acca9529acd6ccb6cd26cdaf684d69cc6f359683f90357be"},
- {file = "backports_zstd-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f1bb3e6d21ebfb22070288b7fb47bbb0baaae604890c4087edf5637debb6bd91"},
- {file = "backports_zstd-1.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:f5fe75e5996b5f4712235f9c63cdb7e5932a9cdf3a41232989f8a3ef1667f784"},
- {file = "backports_zstd-1.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c522469a67fef66998fd9eff2195512ca54d78c6fecdf1c466d2b7752dd810b"},
- {file = "backports_zstd-1.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c28546bcffb88ee38a742e3364338c49672d776ea2c73decc05fbf79f045797e"},
- {file = "backports_zstd-1.0.0-cp313-cp313-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:9719c14984ca99f5567a5974210d04c75aa02b0124653ee1b1d9a39bf0764fc6"},
- {file = "backports_zstd-1.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a31220e8544c2194c4a7c3bd9f7fb0eee3c0ce5f8306e55df762428159ff0512"},
- {file = "backports_zstd-1.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3571e35d6682119daf109678a68fa8a9e29f79487ee7ec2da63a7e97562acb8c"},
- {file = "backports_zstd-1.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:26ccb82bbeb36fffeb3865abe7df9b9b82d6462a488cd2f3c10e91c41c3103cc"},
- {file = "backports_zstd-1.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d90cfb475d6d08c596ae77a7009cdda7374ecd79354fd75185cf029bf2204620"},
- {file = "backports_zstd-1.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0b00c9c22cae8c1f87e2f23f9aeda7fee82ff671672b9f5a161a7ba094d9904b"},
- {file = "backports_zstd-1.0.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a87c4491036954ae6d15edaf1e6d5b1941e13a9df14d6a9952899713fcfb0796"},
- {file = "backports_zstd-1.0.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8ea8c5d283211bc21c9782db7a8504a275a5b97e883b0bf67f6903a3af48f3d3"},
- {file = "backports_zstd-1.0.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e1d12f64d1bd535c782f30b33d1f60c060105d124f9ade22556fefbf36087776"},
- {file = "backports_zstd-1.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df08eb2735363a11a9222203c3e9a478d7569511bdd9aa2cc64a39e0403cf09a"},
- {file = "backports_zstd-1.0.0-cp313-cp313-win32.whl", hash = "sha256:0309f924ec026d2174297754aeb97fe5fa665cfe0f8bc70e7bb82808a7adcd08"},
- {file = "backports_zstd-1.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:d68f7f72579070bfef7890ba5316701c001e90b4455bb5c2591558b9d53a7f6e"},
- {file = "backports_zstd-1.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:911a099122ce7cebed9e1ec64c1fa54a6ab461d6c7cec8d460d8b3a09bbd439f"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:fad9af0c89048a50e67bfd9e3509d710b268d4ae0e47a2bc945dca273a17286d"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:1d0459de16491399e6b6d151213964395ba092ba21b7739756f0507533c8e44f"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:2dcf4c080c0fe8f4ca8f1ff560756ae78e6fada721813c1506f8fd3399996646"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e26b558e0f2413e9499949dd75985a03be008287598916eaa75a67efc52e4f1b"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f0a0c11aee04e0a10e9688ef8d9014af888763507bea85a0d7a7ba5220272996"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c8aa92bf9407ed1ba62234e085876b628ecd9d2636c0e1e23f2dacf3be21af2a"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c78c1eaf3fdea00514afe9636e01f94890f1e4c6e8e1dfede48015364b950705"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4ff181018de5afb1b87edf9a88ec7e62b4b053e75b91ec8ac7819042126ca7cf"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:eed0753c698a21f0d38464c2a6d4d5e770d2ea2e9c3a308f1712d674598a049f"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:18f5d3ed08afcd08b86b305bf167c0f2b582b906742e4bd3c7389050d5b59817"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:7a8c950abe629e5d8ea606e6600dd1d6cd6bddd7a4566cf34201d31244d10ab3"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:973e74f4e1f19f7879a6a7900e9a268522eb4297100a573ed69969df63f94674"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-win32.whl", hash = "sha256:870effb06ffb7623af1c8dac35647a1c4b597d3bb0b3f9895c738bd5ad23666c"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8bb6470186301e84aaa704c8eb339c97dcdec67445e7e197d44665e933807e4e"},
- {file = "backports_zstd-1.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b2d85810393b3be6e8e77d89a165fc67c2a08290a210dbd77e2fc148dbc4106f"},
- {file = "backports_zstd-1.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1315107754808856ddcf187a19cc139cb4a2a65970bd1bafd71718cfd051d32e"},
- {file = "backports_zstd-1.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:96bf0a564af74951adfa6addd1c148ab467ba92172cd23b267dd150b0f47fd9e"},
- {file = "backports_zstd-1.0.0-cp39-cp39-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:d7c1c6ebedf7bc70c1adca3f4624e1e04b2a0d7a389b065f0c5d6244f6be3dae"},
- {file = "backports_zstd-1.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2ea4ff5e162fb61f8421724021eac0a612af0aff2da9e585c96d27c2da924589"},
- {file = "backports_zstd-1.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5a6047fb0bef5bbe519b1e46108847e01a48d002b3dfc69af1423a53d8144dda"},
- {file = "backports_zstd-1.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2d510b422e7b2b6ca142082fa85ac360edf77b73108454335ecfd19071c819ff"},
- {file = "backports_zstd-1.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e6349defa266342802d86343b7fc59ee12048bca5f77a9fcb1c1ab9bb894d09"},
- {file = "backports_zstd-1.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:20b0a1be02b2ee18c74b68a89eec14be98d11f0415a79eb209dce4bc2d6f4e52"},
- {file = "backports_zstd-1.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3595cbc2f4d8a5dc6bd791ba8d9fee2fdfcdfc07206e944c1b3ec3090fcbc99e"},
- {file = "backports_zstd-1.0.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d3eddb298db7a9a1b122c40bcb418a154b6c8f1b54ef7308644e0e67d42c159e"},
- {file = "backports_zstd-1.0.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ef31a9482727e6b335f673a8b8116be186b83ca72be4a07f60684b8220a213e9"},
- {file = "backports_zstd-1.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0a6a6d114058735d042116aa9199b0b436236fddcb5f805fb17310fcadddd441"},
- {file = "backports_zstd-1.0.0-cp39-cp39-win32.whl", hash = "sha256:8aea1bdc89becb21d1df1cdcc6182b2aa9540addaa20569169e01b25b8996f41"},
- {file = "backports_zstd-1.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:23a40a40fb56f4b47ece5e9cb7048c2e93d9eeb81ad5fb4e68adcaeb699d6b98"},
- {file = "backports_zstd-1.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:2f07bd1c1b478bd8a0bbe413439c24ee08ceb6ebc957a97de3666e8f2e612463"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:efa53658c1e617986ed202e7aa8eb23c69fc8f33d01192cd1565e455ed9aa057"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:4386a17c99ce647877298c916f2afeacb238e56cb7cca2d665822a0ee743b5d5"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:cbbb0bda54bda18af99961d7d22d7bc7fedcc7d8ca3a04dcde9189494dbfc87a"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c49048ec50f81b196ab0f3c49c025912eba1c6e55259b99f11ee6e8c04226ab"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6d1fe816c3c31241b0bdcc96364fae689f3e49a923469ad1ad7a9aeb0bbcd67"},
- {file = "backports_zstd-1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:96a57f48d2d64c985393bb4ae15b61097d8fc0d56416e790f7cc09bf9212fb87"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8191c019cefaf074c3f05ebec5ad19ec606b7ac1dc915b66a0820268e6f0e327"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:479270cd6385775dca98accaf304e5f011d94280ad4681d3e925a1b4dfd19aaf"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-manylinux2010_i686.manylinux_2_12_i686.manylinux_2_28_i686.whl", hash = "sha256:3beab43bfda8e453648b9cce5edcceb5add6c42c331873b41ab1d24232d9c2b0"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67469b247c99537b77f7d402580cbb7298fa15ebe3ce6984d89a5b65d4d5a6c2"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6910a9311e7a2987d353f396568f5e401cf4917e2112bf610e62385ad02d8cf4"},
- {file = "backports_zstd-1.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:85f08363b7ca504a8bceaa2d4333a1a307d2b2056f77a13036a81d7aa3c87b2a"},
- {file = "backports_zstd-1.0.0.tar.gz", hash = "sha256:8e99702fd4092c26624b914bcd140d03911a16445ba6a74435b29a190469cce3"},
-]
-
-[[package]]
-name = "beautifulsoup4"
-version = "4.14.2"
-description = "Screen-scraping library"
-optional = false
-python-versions = ">=3.7.0"
-groups = ["eval"]
-files = [
- {file = "beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515"},
- {file = "beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e"},
-]
-
-[package.dependencies]
-soupsieve = ">1.2"
-typing-extensions = ">=4.0.0"
-
-[package.extras]
-cchardet = ["cchardet"]
-chardet = ["chardet"]
-charset-normalizer = ["charset-normalizer"]
-html5lib = ["html5lib"]
-lxml = ["lxml"]
-
-[[package]]
-name = "bidict"
-version = "0.23.1"
-description = "The bidirectional mapping library for Python."
-optional = false
-python-versions = ">=3.8"
-groups = ["test"]
-files = [
- {file = "bidict-0.23.1-py3-none-any.whl", hash = "sha256:5dae8d4d79b552a71cbabc7deb25dfe8ce710b17ff41711e13010ead2abfc3e5"},
- {file = "bidict-0.23.1.tar.gz", hash = "sha256:03069d763bc387bbd20e7d49914e75fc4132a41937fa3405417e1a5a2d006d71"},
-]
-
-[[package]]
-name = "blinker"
-version = "1.9.0"
-description = "Fast, simple object-to-object and broadcast signaling"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "eval", "test"]
-files = [
- {file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"},
- {file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
-]
-
-[[package]]
-name = "boto3"
-version = "1.40.72"
-description = "The AWS SDK for Python"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "boto3-1.40.72-py3-none-any.whl", hash = "sha256:1063a295712f2605d3e463e4dc1fe32fce17cf77a0f4d3bb14249d68533ee856"},
- {file = "boto3-1.40.72.tar.gz", hash = "sha256:58d30dd5e046789a760db7a49f817650b8ff08d8d169e127976a61f44b7c59ad"},
-]
-
-[package.dependencies]
-botocore = ">=1.40.72,<1.41.0"
-jmespath = ">=0.7.1,<2.0.0"
-s3transfer = ">=0.14.0,<0.15.0"
-
-[package.extras]
-crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
-
-[[package]]
-name = "botocore"
-version = "1.40.72"
-description = "Low-level, data-driven core of boto 3."
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "botocore-1.40.72-py3-none-any.whl", hash = "sha256:4f859e5aaf871fe59aac431d6bba59cc0c8ed8a38da2a6a5345700bdc5c74b32"},
- {file = "botocore-1.40.72.tar.gz", hash = "sha256:f69199ff6570695556e733fa052f2739e01e0c592c9b60f843f84c77ba3bcdf3"},
-]
-
-[package.dependencies]
-jmespath = ">=0.7.1,<2.0.0"
-python-dateutil = ">=2.1,<3.0.0"
-urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""}
-
-[package.extras]
-crt = ["awscrt (==0.27.6)"]
-
-[[package]]
-name = "brotli"
-version = "1.2.0"
-description = "Python bindings for the Brotli compression library"
-optional = false
-python-versions = "*"
-groups = ["main", "test"]
-files = [
- {file = "brotli-1.2.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:99cfa69813d79492f0e5d52a20fd18395bc82e671d5d40bd5a91d13e75e468e8"},
- {file = "brotli-1.2.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:3ebe801e0f4e56d17cd386ca6600573e3706ce1845376307f5d2cbd32149b69a"},
- {file = "brotli-1.2.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:a387225a67f619bf16bd504c37655930f910eb03675730fc2ad69d3d8b5e7e92"},
- {file = "brotli-1.2.0-cp27-cp27m-win32.whl", hash = "sha256:b908d1a7b28bc72dfb743be0d4d3f8931f8309f810af66c906ae6cd4127c93cb"},
- {file = "brotli-1.2.0-cp27-cp27m-win_amd64.whl", hash = "sha256:d206a36b4140fbb5373bf1eb73fb9de589bb06afd0d22376de23c5e91d0ab35f"},
- {file = "brotli-1.2.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7e9053f5fb4e0dfab89243079b3e217f2aea4085e4d58c5c06115fc34823707f"},
- {file = "brotli-1.2.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4735a10f738cb5516905a121f32b24ce196ab82cfc1e4ba2e3ad1b371085fd46"},
- {file = "brotli-1.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3b90b767916ac44e93a8e28ce6adf8d551e43affb512f2377c732d486ac6514e"},
- {file = "brotli-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6be67c19e0b0c56365c6a76e393b932fb0e78b3b56b711d180dd7013cb1fd984"},
- {file = "brotli-1.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0bbd5b5ccd157ae7913750476d48099aaf507a79841c0d04a9db4415b14842de"},
- {file = "brotli-1.2.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3f3c908bcc404c90c77d5a073e55271a0a498f4e0756e48127c35d91cf155947"},
- {file = "brotli-1.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1b557b29782a643420e08d75aea889462a4a8796e9a6cf5621ab05a3f7da8ef2"},
- {file = "brotli-1.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81da1b229b1889f25adadc929aeb9dbc4e922bd18561b65b08dd9343cfccca84"},
- {file = "brotli-1.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ff09cd8c5eec3b9d02d2408db41be150d8891c5566addce57513bf546e3d6c6d"},
- {file = "brotli-1.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a1778532b978d2536e79c05dac2d8cd857f6c55cd0c95ace5b03740824e0e2f1"},
- {file = "brotli-1.2.0-cp310-cp310-win32.whl", hash = "sha256:b232029d100d393ae3c603c8ffd7e3fe6f798c5e28ddca5feabb8e8fdb732997"},
- {file = "brotli-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:ef87b8ab2704da227e83a246356a2b179ef826f550f794b2c52cddb4efbd0196"},
- {file = "brotli-1.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:15b33fe93cedc4caaff8a0bd1eb7e3dab1c61bb22a0bf5bdfdfd97cd7da79744"},
- {file = "brotli-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:898be2be399c221d2671d29eed26b6b2713a02c2119168ed914e7d00ceadb56f"},
- {file = "brotli-1.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:350c8348f0e76fff0a0fd6c26755d2653863279d086d3aa2c290a6a7251135dd"},
- {file = "brotli-1.2.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1ad3fda65ae0d93fec742a128d72e145c9c7a99ee2fcd667785d99eb25a7fe"},
- {file = "brotli-1.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40d918bce2b427a0c4ba189df7a006ac0c7277c180aee4617d99e9ccaaf59e6a"},
- {file = "brotli-1.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2a7f1d03727130fc875448b65b127a9ec5d06d19d0148e7554384229706f9d1b"},
- {file = "brotli-1.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:9c79f57faa25d97900bfb119480806d783fba83cd09ee0b33c17623935b05fa3"},
- {file = "brotli-1.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:844a8ceb8483fefafc412f85c14f2aae2fb69567bf2a0de53cdb88b73e7c43ae"},
- {file = "brotli-1.2.0-cp311-cp311-win32.whl", hash = "sha256:aa47441fa3026543513139cb8926a92a8e305ee9c71a6209ef7a97d91640ea03"},
- {file = "brotli-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:022426c9e99fd65d9475dce5c195526f04bb8be8907607e27e747893f6ee3e24"},
- {file = "brotli-1.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:35d382625778834a7f3061b15423919aa03e4f5da34ac8e02c074e4b75ab4f84"},
- {file = "brotli-1.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a61c06b334bd99bc5ae84f1eeb36bfe01400264b3c352f968c6e30a10f9d08b"},
- {file = "brotli-1.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:acec55bb7c90f1dfc476126f9711a8e81c9af7fb617409a9ee2953115343f08d"},
- {file = "brotli-1.2.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:260d3692396e1895c5034f204f0db022c056f9e2ac841593a4cf9426e2a3faca"},
- {file = "brotli-1.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:072e7624b1fc4d601036ab3f4f27942ef772887e876beff0301d261210bca97f"},
- {file = "brotli-1.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adedc4a67e15327dfdd04884873c6d5a01d3e3b6f61406f99b1ed4865a2f6d28"},
- {file = "brotli-1.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7a47ce5c2288702e09dc22a44d0ee6152f2c7eda97b3c8482d826a1f3cfc7da7"},
- {file = "brotli-1.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:af43b8711a8264bb4e7d6d9a6d004c3a2019c04c01127a868709ec29962b6036"},
- {file = "brotli-1.2.0-cp312-cp312-win32.whl", hash = "sha256:e99befa0b48f3cd293dafeacdd0d191804d105d279e0b387a32054c1180f3161"},
- {file = "brotli-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:b35c13ce241abdd44cb8ca70683f20c0c079728a36a996297adb5334adfc1c44"},
- {file = "brotli-1.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9e5825ba2c9998375530504578fd4d5d1059d09621a02065d1b6bfc41a8e05ab"},
- {file = "brotli-1.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0cf8c3b8ba93d496b2fae778039e2f5ecc7cff99df84df337ca31d8f2252896c"},
- {file = "brotli-1.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8565e3cdc1808b1a34714b553b262c5de5fbda202285782173ec137fd13709f"},
- {file = "brotli-1.2.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:26e8d3ecb0ee458a9804f47f21b74845cc823fd1bb19f02272be70774f56e2a6"},
- {file = "brotli-1.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67a91c5187e1eec76a61625c77a6c8c785650f5b576ca732bd33ef58b0dff49c"},
- {file = "brotli-1.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ecdb3b6dc36e6d6e14d3a1bdc6c1057c8cbf80db04031d566eb6080ce283a48"},
- {file = "brotli-1.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3e1b35d56856f3ed326b140d3c6d9db91740f22e14b06e840fe4bb1923439a18"},
- {file = "brotli-1.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54a50a9dad16b32136b2241ddea9e4df159b41247b2ce6aac0b3276a66a8f1e5"},
- {file = "brotli-1.2.0-cp313-cp313-win32.whl", hash = "sha256:1b1d6a4efedd53671c793be6dd760fcf2107da3a52331ad9ea429edf0902f27a"},
- {file = "brotli-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:b63daa43d82f0cdabf98dee215b375b4058cce72871fd07934f179885aad16e8"},
- {file = "brotli-1.2.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6c12dad5cd04530323e723787ff762bac749a7b256a5bece32b2243dd5c27b21"},
- {file = "brotli-1.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3219bd9e69868e57183316ee19c84e03e8f8b5a1d1f2667e1aa8c2f91cb061ac"},
- {file = "brotli-1.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:963a08f3bebd8b75ac57661045402da15991468a621f014be54e50f53a58d19e"},
- {file = "brotli-1.2.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9322b9f8656782414b37e6af884146869d46ab85158201d82bab9abbcb971dc7"},
- {file = "brotli-1.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cf9cba6f5b78a2071ec6fb1e7bd39acf35071d90a81231d67e92d637776a6a63"},
- {file = "brotli-1.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7547369c4392b47d30a3467fe8c3330b4f2e0f7730e45e3103d7d636678a808b"},
- {file = "brotli-1.2.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1530af5c3c275b8524f2e24841cbe2599d74462455e9bae5109e9ff42e9361"},
- {file = "brotli-1.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2d085ded05278d1c7f65560aae97b3160aeb2ea2c0b3e26204856beccb60888"},
- {file = "brotli-1.2.0-cp314-cp314-win32.whl", hash = "sha256:832c115a020e463c2f67664560449a7bea26b0c1fdd690352addad6d0a08714d"},
- {file = "brotli-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:e7c0af964e0b4e3412a0ebf341ea26ec767fa0b4cf81abb5e897c9338b5ad6a3"},
- {file = "brotli-1.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:82676c2781ecf0ab23833796062786db04648b7aae8be139f6b8065e5e7b1518"},
- {file = "brotli-1.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c16ab1ef7bb55651f5836e8e62db1f711d55b82ea08c3b8083ff037157171a69"},
- {file = "brotli-1.2.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e85190da223337a6b7431d92c799fca3e2982abd44e7b8dec69938dcc81c8e9e"},
- {file = "brotli-1.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d8c05b1dfb61af28ef37624385b0029df902ca896a639881f594060b30ffc9a7"},
- {file = "brotli-1.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:465a0d012b3d3e4f1d6146ea019b5c11e3e87f03d1676da1cc3833462e672fb0"},
- {file = "brotli-1.2.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:96fbe82a58cdb2f872fa5d87dedc8477a12993626c446de794ea025bbda625ea"},
- {file = "brotli-1.2.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:1b71754d5b6eda54d16fbbed7fce2d8bc6c052a1b91a35c320247946ee103502"},
- {file = "brotli-1.2.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:66c02c187ad250513c2f4fce973ef402d22f80e0adce734ee4e4efd657b6cb64"},
- {file = "brotli-1.2.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:ba76177fd318ab7b3b9bf6522be5e84c2ae798754b6cc028665490f6e66b5533"},
- {file = "brotli-1.2.0-cp36-cp36m-win32.whl", hash = "sha256:c1702888c9f3383cc2f09eb3e88b8babf5965a54afb79649458ec7c3c7a63e96"},
- {file = "brotli-1.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f8d635cafbbb0c61327f942df2e3f474dde1cff16c3cd0580564774eaba1ee13"},
- {file = "brotli-1.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e80a28f2b150774844c8b454dd288be90d76ba6109670fe33d7ff54d96eb5cb8"},
- {file = "brotli-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b1b799f45da91292ffaa21a473ab3a3054fa78560e8ff67082a185274431c8"},
- {file = "brotli-1.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29b7e6716ee4ea0c59e3b241f682204105f7da084d6254ec61886508efeb43bc"},
- {file = "brotli-1.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:640fe199048f24c474ec6f3eae67c48d286de12911110437a36a87d7c89573a6"},
- {file = "brotli-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:92edab1e2fd6cd5ca605f57d4545b6599ced5dea0fd90b2bcdf8b247a12bd190"},
- {file = "brotli-1.2.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7274942e69b17f9cef76691bcf38f2b2d4c8a5f5dba6ec10958363dcb3308a0a"},
- {file = "brotli-1.2.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:a56ef534b66a749759ebd091c19c03ef81eb8cd96f0d1d16b59127eaf1b97a12"},
- {file = "brotli-1.2.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:5732eff8973dd995549a18ecbd8acd692ac611c5c0bb3f59fa3541ae27b33be3"},
- {file = "brotli-1.2.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:598e88c736f63a0efec8363f9eb34e5b5536b7b6b1821e401afcb501d881f59a"},
- {file = "brotli-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:7ad8cec81f34edf44a1c6a7edf28e7b7806dfb8886e371d95dcf789ccd4e4982"},
- {file = "brotli-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:865cedc7c7c303df5fad14a57bc5db1d4f4f9b2b4d0a7523ddd206f00c121a16"},
- {file = "brotli-1.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ac27a70bda257ae3f380ec8310b0a06680236bea547756c277b5dfe55a2452a8"},
- {file = "brotli-1.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e813da3d2d865e9793ef681d3a6b66fa4b7c19244a45b817d0cceda67e615990"},
- {file = "brotli-1.2.0-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fe11467c42c133f38d42289d0861b6b4f9da31e8087ca2c0d7ebb4543625526"},
- {file = "brotli-1.2.0-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c0d6770111d1879881432f81c369de5cde6e9467be7c682a983747ec800544e2"},
- {file = "brotli-1.2.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:eda5a6d042c698e28bda2507a89b16555b9aa954ef1d750e1c20473481aff675"},
- {file = "brotli-1.2.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3173e1e57cebb6d1de186e46b5680afbd82fd4301d7b2465beebe83ed317066d"},
- {file = "brotli-1.2.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:71a66c1c9be66595d628467401d5976158c97888c2c9379c034e1e2312c5b4f5"},
- {file = "brotli-1.2.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:1e68cdf321ad05797ee41d1d09169e09d40fdf51a725bb148bff892ce04583d7"},
- {file = "brotli-1.2.0-cp38-cp38-win32.whl", hash = "sha256:f16dace5e4d3596eaeb8af334b4d2c820d34b8278da633ce4a00020b2eac981c"},
- {file = "brotli-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:14ef29fc5f310d34fc7696426071067462c9292ed98b5ff5a27ac70a200e5470"},
- {file = "brotli-1.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8d4f47f284bdd28629481c97b5f29ad67544fa258d9091a6ed1fda47c7347cd1"},
- {file = "brotli-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2881416badd2a88a7a14d981c103a52a23a276a553a8aacc1346c2ff47c8dc17"},
- {file = "brotli-1.2.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d39b54b968f4b49b5e845758e202b1035f948b0561ff5e6385e855c96625971"},
- {file = "brotli-1.2.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:95db242754c21a88a79e01504912e537808504465974ebb92931cfca2510469e"},
- {file = "brotli-1.2.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bba6e7e6cfe1e6cb6eb0b7c2736a6059461de1fa2c0ad26cf845de6c078d16c8"},
- {file = "brotli-1.2.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:88ef7d55b7bcf3331572634c3fd0ed327d237ceb9be6066810d39020a3ebac7a"},
- {file = "brotli-1.2.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7fa18d65a213abcfbb2f6cafbb4c58863a8bd6f2103d65203c520ac117d1944b"},
- {file = "brotli-1.2.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:09ac247501d1909e9ee47d309be760c89c990defbb2e0240845c892ea5ff0de4"},
- {file = "brotli-1.2.0-cp39-cp39-win32.whl", hash = "sha256:c25332657dee6052ca470626f18349fc1fe8855a56218e19bd7a8c6ad4952c49"},
- {file = "brotli-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:1ce223652fd4ed3eb2b7f78fbea31c52314baecfac68db44037bb4167062a937"},
- {file = "brotli-1.2.0.tar.gz", hash = "sha256:e310f77e41941c13340a95976fe66a8a95b01e783d430eeaf7a2f87e0a57dd0a"},
-]
-markers = {main = "platform_python_implementation == \"CPython\""}
-
-[[package]]
-name = "brotlicffi"
-version = "1.2.0.0"
-description = "Python CFFI bindings to the Brotli library"
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-markers = "platform_python_implementation != \"CPython\""
-files = [
- {file = "brotlicffi-1.2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b13fb476a96f02e477a506423cb5e7bc21e0e3ac4c060c20ba31c44056e38c68"},
- {file = "brotlicffi-1.2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:17db36fb581f7b951635cd6849553a95c6f2f53c1a707817d06eae5aeff5f6af"},
- {file = "brotlicffi-1.2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:40190192790489a7b054312163d0ce82b07d1b6e706251036898ce1684ef12e9"},
- {file = "brotlicffi-1.2.0.0-cp314-cp314t-win32.whl", hash = "sha256:a8079e8ecc32ecef728036a1d9b7105991ce6a5385cf51ee8c02297c90fb08c2"},
- {file = "brotlicffi-1.2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:ca90c4266704ca0a94de8f101b4ec029624273380574e4cf19301acfa46c61a0"},
- {file = "brotlicffi-1.2.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:9458d08a7ccde8e3c0afedbf2c70a8263227a68dea5ab13590593f4c0a4fd5f4"},
- {file = "brotlicffi-1.2.0.0-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:84e3d0020cf1bd8b8131f4a07819edee9f283721566fe044a20ec792ca8fd8b7"},
- {file = "brotlicffi-1.2.0.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:33cfb408d0cff64cd50bef268c0fed397c46fbb53944aa37264148614a62e990"},
- {file = "brotlicffi-1.2.0.0-cp38-abi3-win32.whl", hash = "sha256:23e5c912fdc6fd37143203820230374d24babd078fc054e18070a647118158f6"},
- {file = "brotlicffi-1.2.0.0-cp38-abi3-win_amd64.whl", hash = "sha256:f139a7cdfe4ae7859513067b736eb44d19fae1186f9e99370092f6915216451b"},
- {file = "brotlicffi-1.2.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fa102a60e50ddbd08de86a63431a722ea216d9bc903b000bf544149cc9b823dc"},
- {file = "brotlicffi-1.2.0.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7d3c4332fc808a94e8c1035950a10d04b681b03ab585ce897ae2a360d479037c"},
- {file = "brotlicffi-1.2.0.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb4eb5830026b79a93bf503ad32b2c5257315e9ffc49e76b2715cffd07c8e3db"},
- {file = "brotlicffi-1.2.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3832c66e00d6d82087f20a972b2fc03e21cd99ef22705225a6f8f418a9158ecc"},
- {file = "brotlicffi-1.2.0.0.tar.gz", hash = "sha256:34345d8d1f9d534fcac2249e57a4c3c8801a33c9942ff9f8574f67a175e17adb"},
-]
-
-[package.dependencies]
-cffi = {version = ">=1.0.0", markers = "python_version < \"3.13\""}
-
-[[package]]
-name = "cachetools"
-version = "5.5.2"
-description = "Extensible memoizing collections and decorators"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"},
- {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"},
-]
-
-[[package]]
-name = "certifi"
-version = "2025.11.12"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"},
- {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"},
-]
-
-[[package]]
-name = "cffi"
-version = "2.0.0"
-description = "Foreign Function Interface for Python calling C code."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "eval", "test"]
-files = [
- {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"},
- {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"},
- {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"},
- {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"},
- {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"},
- {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"},
- {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"},
- {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"},
- {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"},
- {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"},
- {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"},
- {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"},
- {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"},
- {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"},
- {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"},
- {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"},
- {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"},
- {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"},
- {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"},
- {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"},
- {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"},
- {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"},
- {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"},
- {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"},
- {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"},
- {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"},
- {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"},
- {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"},
- {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"},
- {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"},
- {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"},
- {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"},
- {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"},
- {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"},
- {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"},
- {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"},
- {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"},
- {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"},
- {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"},
- {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"},
- {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"},
- {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"},
- {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"},
- {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"},
- {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"},
- {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"},
- {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"},
- {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"},
- {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"},
- {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"},
- {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"},
- {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"},
- {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"},
- {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"},
- {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"},
- {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"},
- {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"},
- {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"},
- {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"},
- {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"},
- {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"},
- {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"},
- {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"},
- {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"},
- {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"},
- {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"},
- {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"},
- {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"},
- {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"},
- {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"},
- {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"},
- {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"},
- {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"},
- {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"},
- {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"},
- {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"},
- {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"},
- {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"},
- {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"},
- {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"},
- {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"},
- {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"},
- {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"},
- {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"},
-]
-markers = {eval = "implementation_name == \"pypy\"", test = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\" or implementation_name == \"pypy\""}
-
-[package.dependencies]
-pycparser = {version = "*", markers = "implementation_name != \"PyPy\""}
-
-[[package]]
-name = "cfgv"
-version = "3.4.0"
-description = "Validate configuration and produce human readable error messages."
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
- {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.4.4"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "charset_normalizer-3.4.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-win32.whl", hash = "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d"},
- {file = "charset_normalizer-3.4.4-cp310-cp310-win_arm64.whl", hash = "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-win32.whl", hash = "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016"},
- {file = "charset_normalizer-3.4.4-cp311-cp311-win_arm64.whl", hash = "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-win32.whl", hash = "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525"},
- {file = "charset_normalizer-3.4.4-cp312-cp312-win_arm64.whl", hash = "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-win32.whl", hash = "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14"},
- {file = "charset_normalizer-3.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-win32.whl", hash = "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c"},
- {file = "charset_normalizer-3.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_armv7l.whl", hash = "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_riscv64.whl", hash = "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-win32.whl", hash = "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa"},
- {file = "charset_normalizer-3.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-win32.whl", hash = "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966"},
- {file = "charset_normalizer-3.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50"},
- {file = "charset_normalizer-3.4.4-py3-none-any.whl", hash = "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f"},
- {file = "charset_normalizer-3.4.4.tar.gz", hash = "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a"},
-]
-
-[[package]]
-name = "click"
-version = "8.1.8"
-description = "Composable command line interface toolkit"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
- {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[package]]
-name = "cloudpickle"
-version = "3.1.2"
-description = "Pickler class to extend the standard pickle.Pickler functionality"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a"},
- {file = "cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414"},
-]
-
-[[package]]
-name = "colorama"
-version = "0.4.6"
-description = "Cross-platform colored terminal text."
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
-groups = ["main", "dev", "eval", "test"]
-markers = "platform_system == \"Windows\" or 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 = "colorlog"
-version = "6.10.1"
-description = "Add colours to the output of Python's logging module."
-optional = false
-python-versions = ">=3.6"
-groups = ["dev"]
-files = [
- {file = "colorlog-6.10.1-py3-none-any.whl", hash = "sha256:2d7e8348291948af66122cff006c9f8da6255d224e7cf8e37d8de2df3bad8c9c"},
- {file = "colorlog-6.10.1.tar.gz", hash = "sha256:eb4ae5cb65fe7fec7773c2306061a8e63e02efc2c72eba9d27b0fa23c94f1321"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-
-[package.extras]
-development = ["black", "flake8", "mypy", "pytest", "types-colorama"]
-
-[[package]]
-name = "comm"
-version = "0.2.3"
-description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc."
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417"},
- {file = "comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971"},
-]
-
-[package.extras]
-test = ["pytest"]
-
-[[package]]
-name = "configargparse"
-version = "1.7.1"
-description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables."
-optional = false
-python-versions = ">=3.6"
-groups = ["test"]
-files = [
- {file = "configargparse-1.7.1-py3-none-any.whl", hash = "sha256:8b586a31f9d873abd1ca527ffbe58863c99f36d896e2829779803125e83be4b6"},
- {file = "configargparse-1.7.1.tar.gz", hash = "sha256:79c2ddae836a1e5914b71d58e4b9adbd9f7779d4e6351a637b7d2d9b6c46d3d9"},
-]
-
-[package.extras]
-test = ["PyYAML", "mock", "pytest"]
-yaml = ["PyYAML"]
-
-[[package]]
-name = "contourpy"
-version = "1.3.3"
-description = "Python library for calculating contours of 2D quadrilateral grids"
-optional = false
-python-versions = ">=3.11"
-groups = ["dev"]
-files = [
- {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"},
- {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"},
- {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"},
- {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"},
- {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"},
- {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"},
- {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"},
- {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"},
- {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"},
- {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"},
- {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"},
- {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"},
- {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"},
- {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"},
- {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"},
- {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"},
- {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"},
- {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"},
- {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"},
- {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"},
- {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"},
- {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"},
- {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"},
- {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"},
- {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"},
- {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"},
- {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"},
- {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"},
- {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"},
- {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"},
- {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"},
- {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"},
- {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"},
- {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"},
- {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"},
- {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"},
- {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"},
- {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"},
- {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"},
- {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"},
- {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"},
- {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"},
- {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"},
- {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"},
- {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"},
- {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"},
- {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"},
- {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"},
- {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"},
- {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"},
- {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"},
- {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"},
- {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"},
- {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"},
- {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"},
- {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"},
- {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"},
- {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"},
- {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"},
- {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"},
- {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"},
- {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"},
- {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"},
- {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"},
- {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"},
- {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"},
- {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"},
- {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"},
- {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"},
- {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"},
- {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"},
- {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"},
-]
-
-[package.dependencies]
-numpy = ">=1.25"
-
-[package.extras]
-bokeh = ["bokeh", "selenium"]
-docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
-mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"]
-test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
-test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"]
-
-[[package]]
-name = "coverage"
-version = "7.11.3"
-description = "Code coverage measurement for Python"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "coverage-7.11.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0c986537abca9b064510f3fd104ba33e98d3036608c7f2f5537f869bc10e1ee5"},
- {file = "coverage-7.11.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:28c5251b3ab1d23e66f1130ca0c419747edfbcb4690de19467cd616861507af7"},
- {file = "coverage-7.11.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4f2bb4ee8dd40f9b2a80bb4adb2aecece9480ba1fa60d9382e8c8e0bd558e2eb"},
- {file = "coverage-7.11.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e5f4bfac975a2138215a38bda599ef00162e4143541cf7dd186da10a7f8e69f1"},
- {file = "coverage-7.11.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f4cbfff5cf01fa07464439a8510affc9df281535f41a1f5312fbd2b59b4ab5c"},
- {file = "coverage-7.11.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:31663572f20bf3406d7ac00d6981c7bbbcec302539d26b5ac596ca499664de31"},
- {file = "coverage-7.11.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9799bd6a910961cb666196b8583ed0ee125fa225c6fdee2cbf00232b861f29d2"},
- {file = "coverage-7.11.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:097acc18bedf2c6e3144eaf09b5f6034926c3c9bb9e10574ffd0942717232507"},
- {file = "coverage-7.11.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:6f033dec603eea88204589175782290a038b436105a8f3637a81c4359df27832"},
- {file = "coverage-7.11.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dd9ca2d44ed8018c90efb72f237a2a140325a4c3339971364d758e78b175f58e"},
- {file = "coverage-7.11.3-cp310-cp310-win32.whl", hash = "sha256:900580bc99c145e2561ea91a2d207e639171870d8a18756eb57db944a017d4bb"},
- {file = "coverage-7.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:c8be5bfcdc7832011b2652db29ed7672ce9d353dd19bce5272ca33dbcf60aaa8"},
- {file = "coverage-7.11.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:200bb89fd2a8a07780eafcdff6463104dec459f3c838d980455cfa84f5e5e6e1"},
- {file = "coverage-7.11.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8d264402fc179776d43e557e1ca4a7d953020d3ee95f7ec19cc2c9d769277f06"},
- {file = "coverage-7.11.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:385977d94fc155f8731c895accdfcc3dd0d9dd9ef90d102969df95d3c637ab80"},
- {file = "coverage-7.11.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0542ddf6107adbd2592f29da9f59f5d9cff7947b5bb4f734805085c327dcffaa"},
- {file = "coverage-7.11.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d60bf4d7f886989ddf80e121a7f4d140d9eac91f1d2385ce8eb6bda93d563297"},
- {file = "coverage-7.11.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0a3b6e32457535df0d41d2d895da46434706dd85dbaf53fbc0d3bd7d914b362"},
- {file = "coverage-7.11.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:876a3ee7fd2613eb79602e4cdb39deb6b28c186e76124c3f29e580099ec21a87"},
- {file = "coverage-7.11.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a730cd0824e8083989f304e97b3f884189efb48e2151e07f57e9e138ab104200"},
- {file = "coverage-7.11.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b5cd111d3ab7390be0c07ad839235d5ad54d2ca497b5f5db86896098a77180a4"},
- {file = "coverage-7.11.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:074e6a5cd38e06671580b4d872c1a67955d4e69639e4b04e87fc03b494c1f060"},
- {file = "coverage-7.11.3-cp311-cp311-win32.whl", hash = "sha256:86d27d2dd7c7c5a44710565933c7dc9cd70e65ef97142e260d16d555667deef7"},
- {file = "coverage-7.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:ca90ef33a152205fb6f2f0c1f3e55c50df4ef049bb0940ebba666edd4cdebc55"},
- {file = "coverage-7.11.3-cp311-cp311-win_arm64.whl", hash = "sha256:56f909a40d68947ef726ce6a34eb38f0ed241ffbe55c5007c64e616663bcbafc"},
- {file = "coverage-7.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b771b59ac0dfb7f139f70c85b42717ef400a6790abb6475ebac1ecee8de782f"},
- {file = "coverage-7.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:603c4414125fc9ae9000f17912dcfd3d3eb677d4e360b85206539240c96ea76e"},
- {file = "coverage-7.11.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:77ffb3b7704eb7b9b3298a01fe4509cef70117a52d50bcba29cffc5f53dd326a"},
- {file = "coverage-7.11.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4d4ca49f5ba432b0755ebb0fc3a56be944a19a16bb33802264bbc7311622c0d1"},
- {file = "coverage-7.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:05fd3fb6edff0c98874d752013588836f458261e5eba587afe4c547bba544afd"},
- {file = "coverage-7.11.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0e920567f8c3a3ce68ae5a42cf7c2dc4bb6cc389f18bff2235dd8c03fa405de5"},
- {file = "coverage-7.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4bec8c7160688bd5a34e65c82984b25409563134d63285d8943d0599efbc448e"},
- {file = "coverage-7.11.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:adb9b7b42c802bd8cb3927de8c1c26368ce50c8fdaa83a9d8551384d77537044"},
- {file = "coverage-7.11.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c8f563b245b4ddb591e99f28e3cd140b85f114b38b7f95b2e42542f0603eb7d7"},
- {file = "coverage-7.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e2a96fdc7643c9517a317553aca13b5cae9bad9a5f32f4654ce247ae4d321405"},
- {file = "coverage-7.11.3-cp312-cp312-win32.whl", hash = "sha256:e8feeb5e8705835f0622af0fe7ff8d5cb388948454647086494d6c41ec142c2e"},
- {file = "coverage-7.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:abb903ffe46bd319d99979cdba350ae7016759bb69f47882242f7b93f3356055"},
- {file = "coverage-7.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:1451464fd855d9bd000c19b71bb7dafea9ab815741fb0bd9e813d9b671462d6f"},
- {file = "coverage-7.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84b892e968164b7a0498ddc5746cdf4e985700b902128421bb5cec1080a6ee36"},
- {file = "coverage-7.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f761dbcf45e9416ec4698e1a7649248005f0064ce3523a47402d1bff4af2779e"},
- {file = "coverage-7.11.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1410bac9e98afd9623f53876fae7d8a5db9f5a0ac1c9e7c5188463cb4b3212e2"},
- {file = "coverage-7.11.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:004cdcea3457c0ea3233622cd3464c1e32ebba9b41578421097402bee6461b63"},
- {file = "coverage-7.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f067ada2c333609b52835ca4d4868645d3b63ac04fb2b9a658c55bba7f667d3"},
- {file = "coverage-7.11.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:07bc7745c945a6d95676953e86ba7cebb9f11de7773951c387f4c07dc76d03f5"},
- {file = "coverage-7.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8bba7e4743e37484ae17d5c3b8eb1ce78b564cb91b7ace2e2182b25f0f764cb5"},
- {file = "coverage-7.11.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbffc22d80d86fbe456af9abb17f7a7766e7b2101f7edaacc3535501691563f7"},
- {file = "coverage-7.11.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:0dba4da36730e384669e05b765a2c49f39514dd3012fcc0398dd66fba8d746d5"},
- {file = "coverage-7.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae12fe90b00b71a71b69f513773310782ce01d5f58d2ceb2b7c595ab9d222094"},
- {file = "coverage-7.11.3-cp313-cp313-win32.whl", hash = "sha256:12d821de7408292530b0d241468b698bce18dd12ecaf45316149f53877885f8c"},
- {file = "coverage-7.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:6bb599052a974bb6cedfa114f9778fedfad66854107cf81397ec87cb9b8fbcf2"},
- {file = "coverage-7.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:bb9d7efdb063903b3fdf77caec7b77c3066885068bdc0d44bc1b0c171033f944"},
- {file = "coverage-7.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:fb58da65e3339b3dbe266b607bb936efb983d86b00b03eb04c4ad5b442c58428"},
- {file = "coverage-7.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8d16bbe566e16a71d123cd66382c1315fcd520c7573652a8074a8fe281b38c6a"},
- {file = "coverage-7.11.3-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8258f10059b5ac837232c589a350a2df4a96406d6d5f2a09ec587cbdd539655"},
- {file = "coverage-7.11.3-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4c5627429f7fbff4f4131cfdd6abd530734ef7761116811a707b88b7e205afd7"},
- {file = "coverage-7.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:465695268414e149bab754c54b0c45c8ceda73dd4a5c3ba255500da13984b16d"},
- {file = "coverage-7.11.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4ebcddfcdfb4c614233cff6e9a3967a09484114a8b2e4f2c7a62dc83676ba13f"},
- {file = "coverage-7.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:13b2066303a1c1833c654d2af0455bb009b6e1727b3883c9964bc5c2f643c1d0"},
- {file = "coverage-7.11.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d8750dd20362a1b80e3cf84f58013d4672f89663aee457ea59336df50fab6739"},
- {file = "coverage-7.11.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ab6212e62ea0e1006531a2234e209607f360d98d18d532c2fa8e403c1afbdd71"},
- {file = "coverage-7.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a6b17c2b5e0b9bb7702449200f93e2d04cb04b1414c41424c08aa1e5d352da76"},
- {file = "coverage-7.11.3-cp313-cp313t-win32.whl", hash = "sha256:426559f105f644b69290ea414e154a0d320c3ad8a2bb75e62884731f69cf8e2c"},
- {file = "coverage-7.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:90a96fcd824564eae6137ec2563bd061d49a32944858d4bdbae5c00fb10e76ac"},
- {file = "coverage-7.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:1e33d0bebf895c7a0905fcfaff2b07ab900885fc78bba2a12291a2cfbab014cc"},
- {file = "coverage-7.11.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fdc5255eb4815babcdf236fa1a806ccb546724c8a9b129fd1ea4a5448a0bf07c"},
- {file = "coverage-7.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fe3425dc6021f906c6325d3c415e048e7cdb955505a94f1eb774dafc779ba203"},
- {file = "coverage-7.11.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4ca5f876bf41b24378ee67c41d688155f0e54cdc720de8ef9ad6544005899240"},
- {file = "coverage-7.11.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9061a3e3c92b27fd8036dafa26f25d95695b6aa2e4514ab16a254f297e664f83"},
- {file = "coverage-7.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abcea3b5f0dc44e1d01c27090bc32ce6ffb7aa665f884f1890710454113ea902"},
- {file = "coverage-7.11.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:68c4eb92997dbaaf839ea13527be463178ac0ddd37a7ac636b8bc11a51af2428"},
- {file = "coverage-7.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:149eccc85d48c8f06547534068c41d69a1a35322deaa4d69ba1561e2e9127e75"},
- {file = "coverage-7.11.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:08c0bcf932e47795c49f0406054824b9d45671362dfc4269e0bc6e4bff010704"},
- {file = "coverage-7.11.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:39764c6167c82d68a2d8c97c33dba45ec0ad9172570860e12191416f4f8e6e1b"},
- {file = "coverage-7.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3224c7baf34e923ffc78cb45e793925539d640d42c96646db62dbd61bbcfa131"},
- {file = "coverage-7.11.3-cp314-cp314-win32.whl", hash = "sha256:c713c1c528284d636cd37723b0b4c35c11190da6f932794e145fc40f8210a14a"},
- {file = "coverage-7.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:c381a252317f63ca0179d2c7918e83b99a4ff3101e1b24849b999a00f9cd4f86"},
- {file = "coverage-7.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:3e33a968672be1394eded257ec10d4acbb9af2ae263ba05a99ff901bb863557e"},
- {file = "coverage-7.11.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f9c96a29c6d65bd36a91f5634fef800212dff69dacdb44345c4c9783943ab0df"},
- {file = "coverage-7.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2ec27a7a991d229213c8070d31e3ecf44d005d96a9edc30c78eaeafaa421c001"},
- {file = "coverage-7.11.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:72c8b494bd20ae1c58528b97c4a67d5cfeafcb3845c73542875ecd43924296de"},
- {file = "coverage-7.11.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:60ca149a446da255d56c2a7a813b51a80d9497a62250532598d249b3cdb1a926"},
- {file = "coverage-7.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb5069074db19a534de3859c43eec78e962d6d119f637c41c8e028c5ab3f59dd"},
- {file = "coverage-7.11.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:ac5d5329c9c942bbe6295f4251b135d860ed9f86acd912d418dce186de7c19ac"},
- {file = "coverage-7.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e22539b676fafba17f0a90ac725f029a309eb6e483f364c86dcadee060429d46"},
- {file = "coverage-7.11.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2376e8a9c889016f25472c452389e98bc6e54a19570b107e27cde9d47f387b64"},
- {file = "coverage-7.11.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4234914b8c67238a3c4af2bba648dc716aa029ca44d01f3d51536d44ac16854f"},
- {file = "coverage-7.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f0b4101e2b3c6c352ff1f70b3a6fcc7c17c1ab1a91ccb7a33013cb0782af9820"},
- {file = "coverage-7.11.3-cp314-cp314t-win32.whl", hash = "sha256:305716afb19133762e8cf62745c46c4853ad6f9eeba54a593e373289e24ea237"},
- {file = "coverage-7.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:9245bd392572b9f799261c4c9e7216bafc9405537d0f4ce3ad93afe081a12dc9"},
- {file = "coverage-7.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:9a1d577c20b4334e5e814c3d5fe07fa4a8c3ae42a601945e8d7940bab811d0bd"},
- {file = "coverage-7.11.3-py3-none-any.whl", hash = "sha256:351511ae28e2509c8d8cae5311577ea7dd511ab8e746ffc8814a0896c3d33fbe"},
- {file = "coverage-7.11.3.tar.gz", hash = "sha256:0f59387f5e6edbbffec2281affb71cdc85e0776c1745150a3ab9b6c1d016106b"},
-]
-
-[package.extras]
-toml = ["tomli ; python_full_version <= \"3.11.0a6\""]
-
-[[package]]
-name = "cycler"
-version = "0.12.1"
-description = "Composable style cycles"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
- {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
-]
-
-[package.extras]
-docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
-tests = ["pytest", "pytest-cov", "pytest-xdist"]
-
-[[package]]
-name = "debugpy"
-version = "1.8.17"
-description = "An implementation of the Debug Adapter Protocol for Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "debugpy-1.8.17-cp310-cp310-macosx_15_0_x86_64.whl", hash = "sha256:c41d2ce8bbaddcc0009cc73f65318eedfa3dbc88a8298081deb05389f1ab5542"},
- {file = "debugpy-1.8.17-cp310-cp310-manylinux_2_34_x86_64.whl", hash = "sha256:1440fd514e1b815edd5861ca394786f90eb24960eb26d6f7200994333b1d79e3"},
- {file = "debugpy-1.8.17-cp310-cp310-win32.whl", hash = "sha256:3a32c0af575749083d7492dc79f6ab69f21b2d2ad4cd977a958a07d5865316e4"},
- {file = "debugpy-1.8.17-cp310-cp310-win_amd64.whl", hash = "sha256:a3aad0537cf4d9c1996434be68c6c9a6d233ac6f76c2a482c7803295b4e4f99a"},
- {file = "debugpy-1.8.17-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:d3fce3f0e3de262a3b67e69916d001f3e767661c6e1ee42553009d445d1cd840"},
- {file = "debugpy-1.8.17-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:c6bdf134457ae0cac6fb68205776be635d31174eeac9541e1d0c062165c6461f"},
- {file = "debugpy-1.8.17-cp311-cp311-win32.whl", hash = "sha256:e79a195f9e059edfe5d8bf6f3749b2599452d3e9380484cd261f6b7cd2c7c4da"},
- {file = "debugpy-1.8.17-cp311-cp311-win_amd64.whl", hash = "sha256:b532282ad4eca958b1b2d7dbcb2b7218e02cb934165859b918e3b6ba7772d3f4"},
- {file = "debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d"},
- {file = "debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc"},
- {file = "debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf"},
- {file = "debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464"},
- {file = "debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464"},
- {file = "debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088"},
- {file = "debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83"},
- {file = "debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420"},
- {file = "debugpy-1.8.17-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:045290c010bcd2d82bc97aa2daf6837443cd52f6328592698809b4549babcee1"},
- {file = "debugpy-1.8.17-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:b69b6bd9dba6a03632534cdf67c760625760a215ae289f7489a452af1031fe1f"},
- {file = "debugpy-1.8.17-cp314-cp314-win32.whl", hash = "sha256:5c59b74aa5630f3a5194467100c3b3d1c77898f9ab27e3f7dc5d40fc2f122670"},
- {file = "debugpy-1.8.17-cp314-cp314-win_amd64.whl", hash = "sha256:893cba7bb0f55161de4365584b025f7064e1f88913551bcd23be3260b231429c"},
- {file = "debugpy-1.8.17-cp38-cp38-macosx_15_0_x86_64.whl", hash = "sha256:8deb4e31cd575c9f9370042876e078ca118117c1b5e1f22c32befcfbb6955f0c"},
- {file = "debugpy-1.8.17-cp38-cp38-manylinux_2_34_x86_64.whl", hash = "sha256:b75868b675949a96ab51abc114c7163f40ff0d8f7d6d5fd63f8932fd38e9c6d7"},
- {file = "debugpy-1.8.17-cp38-cp38-win32.whl", hash = "sha256:17e456da14848d618662354e1dccfd5e5fb75deec3d1d48dc0aa0baacda55860"},
- {file = "debugpy-1.8.17-cp38-cp38-win_amd64.whl", hash = "sha256:e851beb536a427b5df8aa7d0c7835b29a13812f41e46292ff80b2ef77327355a"},
- {file = "debugpy-1.8.17-cp39-cp39-macosx_15_0_x86_64.whl", hash = "sha256:f2ac8055a0c4a09b30b931100996ba49ef334c6947e7ae365cdd870416d7513e"},
- {file = "debugpy-1.8.17-cp39-cp39-manylinux_2_34_x86_64.whl", hash = "sha256:eaa85bce251feca8e4c87ce3b954aba84b8c645b90f0e6a515c00394a9f5c0e7"},
- {file = "debugpy-1.8.17-cp39-cp39-win32.whl", hash = "sha256:b13eea5587e44f27f6c48588b5ad56dcb74a4f3a5f89250443c94587f3eb2ea1"},
- {file = "debugpy-1.8.17-cp39-cp39-win_amd64.whl", hash = "sha256:bb1bbf92317e1f35afcf3ef0450219efb3afe00be79d8664b250ac0933b9015f"},
- {file = "debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef"},
- {file = "debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e"},
-]
-
-[[package]]
-name = "decorator"
-version = "5.2.1"
-description = "Decorators for Humans"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a"},
- {file = "decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360"},
-]
-
-[[package]]
-name = "deepeval"
-version = "3.8.8"
-description = "The LLM Evaluation Framework"
-optional = false
-python-versions = "<4.0,>=3.9"
-groups = ["dev"]
-files = [
- {file = "deepeval-3.8.8-py3-none-any.whl", hash = "sha256:32a188a478abeeede896dcd524ac142d1c16948bfd023ce4457e6790ebe4689b"},
- {file = "deepeval-3.8.8.tar.gz", hash = "sha256:389c1742f02121525ecfe40c3d613f76fd418ad0ac0b843df715a9b460b5e679"},
-]
-
-[package.dependencies]
-aiohttp = "*"
-click = ">=8.0.0,<8.4.0"
-grpcio = ">=1.67.1,<2.0.0"
-jinja2 = "*"
-nest_asyncio = "*"
-openai = "*"
-opentelemetry-api = ">=1.24.0,<2.0.0"
-opentelemetry-sdk = ">=1.24.0,<2.0.0"
-portalocker = "*"
-posthog = ">=5.4.0,<6.0.0"
-pydantic = ">=2.11.7,<3.0.0"
-pydantic-settings = ">=2.10.1,<3.0.0"
-pyfiglet = "*"
-pytest = "*"
-pytest-asyncio = "*"
-pytest-repeat = "*"
-pytest-rerunfailures = "*"
-pytest-xdist = "*"
-python-dotenv = ">=1.1.1,<2.0.0"
-requests = ">=2.31.0,<3.0.0"
-rich = ">=13.6.0,<15.0.0"
-sentry-sdk = "*"
-setuptools = "*"
-tabulate = ">=0.9.0,<0.10.0"
-tenacity = ">=8.0.0,<=10.0.0"
-tqdm = ">=4.66.1,<5.0.0"
-typer = ">=0.9,<1.0.0"
-wheel = "*"
-
-[[package]]
-name = "diskcache"
-version = "5.6.3"
-description = "Disk Cache -- Disk and file backed persistent cache."
-optional = false
-python-versions = ">=3"
-groups = ["dev"]
-files = [
- {file = "diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19"},
- {file = "diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc"},
-]
-
-[[package]]
-name = "distlib"
-version = "0.4.0"
-description = "Distribution utilities"
-optional = false
-python-versions = "*"
-groups = ["dev"]
-files = [
- {file = "distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16"},
- {file = "distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d"},
-]
-
-[[package]]
-name = "distro"
-version = "1.9.0"
-description = "Distro - an OS platform information API"
-optional = false
-python-versions = ">=3.6"
-groups = ["main", "dev"]
-files = [
- {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"},
- {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"},
-]
-
-[[package]]
-name = "docker"
-version = "7.1.0"
-description = "A Python library for the Docker Engine API."
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "docker-7.1.0-py3-none-any.whl", hash = "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"},
- {file = "docker-7.1.0.tar.gz", hash = "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c"},
-]
-
-[package.dependencies]
-pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""}
-requests = ">=2.26.0"
-urllib3 = ">=1.26.0"
-
-[package.extras]
-dev = ["coverage (==7.2.7)", "pytest (==7.4.2)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.1.0)", "ruff (==0.1.8)"]
-docs = ["myst-parser (==0.18.0)", "sphinx (==5.1.1)"]
-ssh = ["paramiko (>=2.4.3)"]
-websockets = ["websocket-client (>=1.3.0)"]
-
-[[package]]
-name = "dspy"
-version = "3.0.4"
-description = "DSPy"
-optional = false
-python-versions = "<3.14,>=3.10"
-groups = ["dev"]
-files = [
- {file = "dspy-3.0.4-py3-none-any.whl", hash = "sha256:c0a88c7936f41f6f613ee6ca8cd92e63746ff2bd780e3896615ade7628eb6a6a"},
- {file = "dspy-3.0.4.tar.gz", hash = "sha256:cb4529df9a91353a16144d9d94ba6ff25f36fc5adfd921f127f4c49d0e309fb8"},
-]
-
-[package.dependencies]
-anyio = "*"
-asyncer = "0.0.8"
-backoff = ">=2.2"
-cachetools = ">=5.5.0"
-cloudpickle = ">=3.0.0"
-diskcache = ">=5.6.0"
-gepa = {version = "0.0.17", extras = ["dspy"]}
-joblib = ">=1.3,<2.0"
-json-repair = ">=0.30.0"
-litellm = ">=1.64.0"
-magicattr = ">=0.1.6"
-numpy = ">=1.26.0"
-openai = ">=0.28.1"
-optuna = ">=3.4.0"
-orjson = ">=3.9.0"
-pillow = ">=10.1.0"
-pydantic = ">=2.0"
-regex = ">=2023.10.3"
-requests = ">=2.31.0"
-rich = ">=13.7.1"
-tenacity = ">=8.2.3"
-tqdm = ">=4.66.1"
-xxhash = ">=3.5.0"
-
-[package.extras]
-anthropic = ["anthropic (>=0.18.0,<1.0.0)"]
-dev = ["build (>=1.0.3)", "datamodel_code_generator (>=0.26.3)", "litellm (>=1.64.0) ; sys_platform == \"win32\"", "litellm[proxy] (>=1.64.0) ; sys_platform != \"win32\"", "pillow (>=10.1.0)", "pre-commit (>=3.7.0)", "pytest (>=6.2.5)", "pytest-asyncio (>=0.26.0)", "pytest-mock (>=3.12.0)", "ruff (>=0.3.0)"]
-langchain = ["langchain_core"]
-mcp = ["mcp ; python_version >= \"3.10\""]
-test-extras = ["datasets (>=2.14.6)", "langchain_core", "mcp ; python_version >= \"3.10\"", "optuna (>=3.4.0)", "pandas (>=2.1.1)"]
-weaviate = ["weaviate-client (>=4.5.4,<4.6.0)"]
-
-[[package]]
-name = "dspy-ai"
-version = "2.6.27"
-description = "DSPy"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "dspy_ai-2.6.27-py3-none-any.whl", hash = "sha256:e7d4d3328dd05098efbedbd72d1c324a2317e4693638eb8755926c9ff0f64861"},
- {file = "dspy_ai-2.6.27.tar.gz", hash = "sha256:93d363e2ceb3745554133c8849e3eea356653707a6760eadfb9533d7d9e5f330"},
-]
-
-[package.dependencies]
-dspy = ">=2.6.5"
-
-[[package]]
-name = "execnet"
-version = "2.1.2"
-description = "execnet: rapid multi-Python deployment"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec"},
- {file = "execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd"},
-]
-
-[package.extras]
-testing = ["hatch", "pre-commit", "pytest", "tox"]
-
-[[package]]
-name = "executing"
-version = "2.2.1"
-description = "Get the currently executing AST node of a frame, and other information"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017"},
- {file = "executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4"},
-]
-
-[package.extras]
-tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich ; python_version >= \"3.11\""]
-
-[[package]]
-name = "extra-streamlit-components"
-version = "0.1.81"
-description = "An all-in-one place, to find complex or just natively unavailable components on streamlit."
-optional = false
-python-versions = ">=3.6"
-groups = ["dev"]
-files = [
- {file = "extra_streamlit_components-0.1.81-py3-none-any.whl", hash = "sha256:11a4651dbd03cac04edfbb8711757b1d10e3cdf280b8fa3a43f970d05e684619"},
- {file = "extra_streamlit_components-0.1.81.tar.gz", hash = "sha256:eb9beb7bacfe8b3d238f1888a21c78ac6cfa569341be484bca08c3ea0b15f20d"},
-]
-
-[package.dependencies]
-streamlit = ">=1.40.1"
-
-[[package]]
-name = "fastapi"
-version = "0.121.1"
-description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "fastapi-0.121.1-py3-none-any.whl", hash = "sha256:2c5c7028bc3a58d8f5f09aecd3fd88a000ccc0c5ad627693264181a3c33aa1fc"},
- {file = "fastapi-0.121.1.tar.gz", hash = "sha256:b6dba0538fd15dab6fe4d3e5493c3957d8a9e1e9257f56446b5859af66f32441"},
-]
-
-[package.dependencies]
-annotated-doc = ">=0.0.2"
-pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
-starlette = ">=0.40.0,<0.50.0"
-typing-extensions = ">=4.8.0"
-
-[package.extras]
-all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=3.1.5)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.18)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
-standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
-standard-no-fastapi-cloud-cli = ["email-validator (>=2.0.0)", "fastapi-cli[standard-no-fastapi-cloud-cli] (>=0.0.8)", "httpx (>=0.23.0,<1.0.0)", "jinja2 (>=3.1.5)", "python-multipart (>=0.0.18)", "uvicorn[standard] (>=0.12.0)"]
-
-[[package]]
-name = "fastjsonschema"
-version = "2.21.2"
-description = "Fastest Python implementation of JSON schema"
-optional = false
-python-versions = "*"
-groups = ["eval"]
-files = [
- {file = "fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463"},
- {file = "fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de"},
-]
-
-[package.extras]
-devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"]
-
-[[package]]
-name = "fastuuid"
-version = "0.14.0"
-description = "Python bindings to Rust's UUID library."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "fastuuid-0.14.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:6e6243d40f6c793c3e2ee14c13769e341b90be5ef0c23c82fa6515a96145181a"},
- {file = "fastuuid-0.14.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:13ec4f2c3b04271f62be2e1ce7e95ad2dd1cf97e94503a3760db739afbd48f00"},
- {file = "fastuuid-0.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b2fdd48b5e4236df145a149d7125badb28e0a383372add3fbaac9a6b7a394470"},
- {file = "fastuuid-0.14.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f74631b8322d2780ebcf2d2d75d58045c3e9378625ec51865fe0b5620800c39d"},
- {file = "fastuuid-0.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83cffc144dc93eb604b87b179837f2ce2af44871a7b323f2bfed40e8acb40ba8"},
- {file = "fastuuid-0.14.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a771f135ab4523eb786e95493803942a5d1fc1610915f131b363f55af53b219"},
- {file = "fastuuid-0.14.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4edc56b877d960b4eda2c4232f953a61490c3134da94f3c28af129fb9c62a4f6"},
- {file = "fastuuid-0.14.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bcc96ee819c282e7c09b2eed2b9bd13084e3b749fdb2faf58c318d498df2efbe"},
- {file = "fastuuid-0.14.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7a3c0bca61eacc1843ea97b288d6789fbad7400d16db24e36a66c28c268cfe3d"},
- {file = "fastuuid-0.14.0-cp310-cp310-win32.whl", hash = "sha256:7f2f3efade4937fae4e77efae1af571902263de7b78a0aee1a1653795a093b2a"},
- {file = "fastuuid-0.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:ae64ba730d179f439b0736208b4c279b8bc9c089b102aec23f86512ea458c8a4"},
- {file = "fastuuid-0.14.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:73946cb950c8caf65127d4e9a325e2b6be0442a224fd51ba3b6ac44e1912ce34"},
- {file = "fastuuid-0.14.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:12ac85024637586a5b69645e7ed986f7535106ed3013640a393a03e461740cb7"},
- {file = "fastuuid-0.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:05a8dde1f395e0c9b4be515b7a521403d1e8349443e7641761af07c7ad1624b1"},
- {file = "fastuuid-0.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09378a05020e3e4883dfdab438926f31fea15fd17604908f3d39cbeb22a0b4dc"},
- {file = "fastuuid-0.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbb0c4b15d66b435d2538f3827f05e44e2baafcc003dd7d8472dc67807ab8fd8"},
- {file = "fastuuid-0.14.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cd5a7f648d4365b41dbf0e38fe8da4884e57bed4e77c83598e076ac0c93995e7"},
- {file = "fastuuid-0.14.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c0a94245afae4d7af8c43b3159d5e3934c53f47140be0be624b96acd672ceb73"},
- {file = "fastuuid-0.14.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b29e23c97e77c3a9514d70ce343571e469098ac7f5a269320a0f0b3e193ab36"},
- {file = "fastuuid-0.14.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1e690d48f923c253f28151b3a6b4e335f2b06bf669c68a02665bc150b7839e94"},
- {file = "fastuuid-0.14.0-cp311-cp311-win32.whl", hash = "sha256:a6f46790d59ab38c6aa0e35c681c0484b50dc0acf9e2679c005d61e019313c24"},
- {file = "fastuuid-0.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:e150eab56c95dc9e3fefc234a0eedb342fac433dacc273cd4d150a5b0871e1fa"},
- {file = "fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77e94728324b63660ebf8adb27055e92d2e4611645bf12ed9d88d30486471d0a"},
- {file = "fastuuid-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:caa1f14d2102cb8d353096bc6ef6c13b2c81f347e6ab9d6fbd48b9dea41c153d"},
- {file = "fastuuid-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d23ef06f9e67163be38cece704170486715b177f6baae338110983f99a72c070"},
- {file = "fastuuid-0.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c9ec605ace243b6dbe3bd27ebdd5d33b00d8d1d3f580b39fdd15cd96fd71796"},
- {file = "fastuuid-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:808527f2407f58a76c916d6aa15d58692a4a019fdf8d4c32ac7ff303b7d7af09"},
- {file = "fastuuid-0.14.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fb3c0d7fef6674bbeacdd6dbd386924a7b60b26de849266d1ff6602937675c8"},
- {file = "fastuuid-0.14.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab3f5d36e4393e628a4df337c2c039069344db5f4b9d2a3c9cea48284f1dd741"},
- {file = "fastuuid-0.14.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b9a0ca4f03b7e0b01425281ffd44e99d360e15c895f1907ca105854ed85e2057"},
- {file = "fastuuid-0.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3acdf655684cc09e60fb7e4cf524e8f42ea760031945aa8086c7eae2eeeabeb8"},
- {file = "fastuuid-0.14.0-cp312-cp312-win32.whl", hash = "sha256:9579618be6280700ae36ac42c3efd157049fe4dd40ca49b021280481c78c3176"},
- {file = "fastuuid-0.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:d9e4332dc4ba054434a9594cbfaf7823b57993d7d8e7267831c3e059857cf397"},
- {file = "fastuuid-0.14.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:77a09cb7427e7af74c594e409f7731a0cf887221de2f698e1ca0ebf0f3139021"},
- {file = "fastuuid-0.14.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:9bd57289daf7b153bfa3e8013446aa144ce5e8c825e9e366d455155ede5ea2dc"},
- {file = "fastuuid-0.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ac60fc860cdf3c3f327374db87ab8e064c86566ca8c49d2e30df15eda1b0c2d5"},
- {file = "fastuuid-0.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab32f74bd56565b186f036e33129da77db8be09178cd2f5206a5d4035fb2a23f"},
- {file = "fastuuid-0.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33e678459cf4addaedd9936bbb038e35b3f6b2061330fd8f2f6a1d80414c0f87"},
- {file = "fastuuid-0.14.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1e3cc56742f76cd25ecb98e4b82a25f978ccffba02e4bdce8aba857b6d85d87b"},
- {file = "fastuuid-0.14.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cb9a030f609194b679e1660f7e32733b7a0f332d519c5d5a6a0a580991290022"},
- {file = "fastuuid-0.14.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:09098762aad4f8da3a888eb9ae01c84430c907a297b97166b8abc07b640f2995"},
- {file = "fastuuid-0.14.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1383fff584fa249b16329a059c68ad45d030d5a4b70fb7c73a08d98fd53bcdab"},
- {file = "fastuuid-0.14.0-cp313-cp313-win32.whl", hash = "sha256:a0809f8cc5731c066c909047f9a314d5f536c871a7a22e815cc4967c110ac9ad"},
- {file = "fastuuid-0.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:0df14e92e7ad3276327631c9e7cec09e32572ce82089c55cb1bb8df71cf394ed"},
- {file = "fastuuid-0.14.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:b852a870a61cfc26c884af205d502881a2e59cc07076b60ab4a951cc0c94d1ad"},
- {file = "fastuuid-0.14.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c7502d6f54cd08024c3ea9b3514e2d6f190feb2f46e6dbcd3747882264bb5f7b"},
- {file = "fastuuid-0.14.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1ca61b592120cf314cfd66e662a5b54a578c5a15b26305e1b8b618a6f22df714"},
- {file = "fastuuid-0.14.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa75b6657ec129d0abded3bec745e6f7ab642e6dba3a5272a68247e85f5f316f"},
- {file = "fastuuid-0.14.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8a0dfea3972200f72d4c7df02c8ac70bad1bb4c58d7e0ec1e6f341679073a7f"},
- {file = "fastuuid-0.14.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1bf539a7a95f35b419f9ad105d5a8a35036df35fdafae48fb2fd2e5f318f0d75"},
- {file = "fastuuid-0.14.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:9a133bf9cc78fdbd1179cb58a59ad0100aa32d8675508150f3658814aeefeaa4"},
- {file = "fastuuid-0.14.0-cp314-cp314-musllinux_1_1_i686.whl", hash = "sha256:f54d5b36c56a2d5e1a31e73b950b28a0d83eb0c37b91d10408875a5a29494bad"},
- {file = "fastuuid-0.14.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:ec27778c6ca3393ef662e2762dba8af13f4ec1aaa32d08d77f71f2a70ae9feb8"},
- {file = "fastuuid-0.14.0-cp314-cp314-win32.whl", hash = "sha256:e23fc6a83f112de4be0cc1990e5b127c27663ae43f866353166f87df58e73d06"},
- {file = "fastuuid-0.14.0-cp314-cp314-win_amd64.whl", hash = "sha256:df61342889d0f5e7a32f7284e55ef95103f2110fee433c2ae7c2c0956d76ac8a"},
- {file = "fastuuid-0.14.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:47c821f2dfe95909ead0085d4cb18d5149bca704a2b03e03fb3f81a5202d8cea"},
- {file = "fastuuid-0.14.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:3964bab460c528692c70ab6b2e469dd7a7b152fbe8c18616c58d34c93a6cf8d4"},
- {file = "fastuuid-0.14.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c501561e025b7aea3508719c5801c360c711d5218fc4ad5d77bf1c37c1a75779"},
- {file = "fastuuid-0.14.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dce5d0756f046fa792a40763f36accd7e466525c5710d2195a038f93ff96346"},
- {file = "fastuuid-0.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193ca10ff553cf3cc461572da83b5780fc0e3eea28659c16f89ae5202f3958d4"},
- {file = "fastuuid-0.14.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0737606764b29785566f968bd8005eace73d3666bd0862f33a760796e26d1ede"},
- {file = "fastuuid-0.14.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0976c0dff7e222513d206e06341503f07423aceb1db0b83ff6851c008ceee06"},
- {file = "fastuuid-0.14.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6fbc49a86173e7f074b1a9ec8cf12ca0d54d8070a85a06ebf0e76c309b84f0d0"},
- {file = "fastuuid-0.14.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:de01280eabcd82f7542828ecd67ebf1551d37203ecdfd7ab1f2e534edb78d505"},
- {file = "fastuuid-0.14.0-cp38-cp38-win32.whl", hash = "sha256:af5967c666b7d6a377098849b07f83462c4fedbafcf8eb8bc8ff05dcbe8aa209"},
- {file = "fastuuid-0.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3091e63acf42f56a6f74dc65cfdb6f99bfc79b5913c8a9ac498eb7ca09770a8"},
- {file = "fastuuid-0.14.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:2ec3d94e13712a133137b2805073b65ecef4a47217d5bac15d8ac62376cefdb4"},
- {file = "fastuuid-0.14.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:139d7ff12bb400b4a0c76be64c28cbe2e2edf60b09826cbfd85f33ed3d0bbe8b"},
- {file = "fastuuid-0.14.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d55b7e96531216fc4f071909e33e35e5bfa47962ae67d9e84b00a04d6e8b7173"},
- {file = "fastuuid-0.14.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0eb25f0fd935e376ac4334927a59e7c823b36062080e2e13acbaf2af15db836"},
- {file = "fastuuid-0.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:089c18018fdbdda88a6dafd7d139f8703a1e7c799618e33ea25eb52503d28a11"},
- {file = "fastuuid-0.14.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fc37479517d4d70c08696960fad85494a8a7a0af4e93e9a00af04d74c59f9e3"},
- {file = "fastuuid-0.14.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:73657c9f778aba530bc96a943d30e1a7c80edb8278df77894fe9457540df4f85"},
- {file = "fastuuid-0.14.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d31f8c257046b5617fc6af9c69be066d2412bdef1edaa4bdf6a214cf57806105"},
- {file = "fastuuid-0.14.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5816d41f81782b209843e52fdef757a361b448d782452d96abedc53d545da722"},
- {file = "fastuuid-0.14.0-cp39-cp39-win32.whl", hash = "sha256:448aa6833f7a84bfe37dd47e33df83250f404d591eb83527fa2cac8d1e57d7f3"},
- {file = "fastuuid-0.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:84b0779c5abbdec2a9511d5ffbfcd2e53079bf889824b32be170c0d8ef5fc74c"},
- {file = "fastuuid-0.14.0.tar.gz", hash = "sha256:178947fc2f995b38497a74172adee64fdeb8b7ec18f2a5934d037641ba265d26"},
-]
-
-[[package]]
-name = "filelock"
-version = "3.20.3"
-description = "A platform independent file lock."
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "filelock-3.20.3-py3-none-any.whl", hash = "sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1"},
- {file = "filelock-3.20.3.tar.gz", hash = "sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1"},
-]
-
-[[package]]
-name = "flask"
-version = "3.1.2"
-description = "A simple framework for building complex web applications."
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c"},
- {file = "flask-3.1.2.tar.gz", hash = "sha256:bf656c15c80190ed628ad08cdfd3aaa35beb087855e2f494910aa3774cc4fd87"},
-]
-
-[package.dependencies]
-blinker = ">=1.9.0"
-click = ">=8.1.3"
-itsdangerous = ">=2.2.0"
-jinja2 = ">=3.1.2"
-markupsafe = ">=2.1.1"
-werkzeug = ">=3.1.0"
-
-[package.extras]
-async = ["asgiref (>=3.2)"]
-dotenv = ["python-dotenv"]
-
-[[package]]
-name = "flask-cors"
-version = "6.0.1"
-description = "A Flask extension simplifying CORS support"
-optional = false
-python-versions = "<4.0,>=3.9"
-groups = ["test"]
-files = [
- {file = "flask_cors-6.0.1-py3-none-any.whl", hash = "sha256:c7b2cbfb1a31aa0d2e5341eea03a6805349f7a61647daee1a15c46bbe981494c"},
- {file = "flask_cors-6.0.1.tar.gz", hash = "sha256:d81bcb31f07b0985be7f48406247e9243aced229b7747219160a0559edd678db"},
-]
-
-[package.dependencies]
-flask = ">=0.9"
-Werkzeug = ">=0.7"
-
-[[package]]
-name = "flask-login"
-version = "0.6.3"
-description = "User authentication and session management for Flask."
-optional = false
-python-versions = ">=3.7"
-groups = ["test"]
-files = [
- {file = "Flask-Login-0.6.3.tar.gz", hash = "sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333"},
- {file = "Flask_Login-0.6.3-py3-none-any.whl", hash = "sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d"},
-]
-
-[package.dependencies]
-Flask = ">=1.0.4"
-Werkzeug = ">=1.0.1"
-
-[[package]]
-name = "fonttools"
-version = "4.61.1"
-description = "Tools to manipulate font files"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c7db70d57e5e1089a274cbb2b1fd635c9a24de809a231b154965d415d6c6d24"},
- {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5fe9fd43882620017add5eabb781ebfbc6998ee49b35bd7f8f79af1f9f99a958"},
- {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8db08051fc9e7d8bc622f2112511b8107d8f27cd89e2f64ec45e9825e8288da"},
- {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a76d4cb80f41ba94a6691264be76435e5f72f2cb3cab0b092a6212855f71c2f6"},
- {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a13fc8aeb24bad755eea8f7f9d409438eb94e82cf86b08fe77a03fbc8f6a96b1"},
- {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b846a1fcf8beadeb9ea4f44ec5bdde393e2f1569e17d700bfc49cd69bde75881"},
- {file = "fonttools-4.61.1-cp310-cp310-win32.whl", hash = "sha256:78a7d3ab09dc47ac1a363a493e6112d8cabed7ba7caad5f54dbe2f08676d1b47"},
- {file = "fonttools-4.61.1-cp310-cp310-win_amd64.whl", hash = "sha256:eff1ac3cc66c2ac7cda1e64b4e2f3ffef474b7335f92fc3833fc632d595fcee6"},
- {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09"},
- {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37"},
- {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb"},
- {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9"},
- {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87"},
- {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56"},
- {file = "fonttools-4.61.1-cp311-cp311-win32.whl", hash = "sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a"},
- {file = "fonttools-4.61.1-cp311-cp311-win_amd64.whl", hash = "sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7"},
- {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e"},
- {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2"},
- {file = "fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796"},
- {file = "fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d"},
- {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8"},
- {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0"},
- {file = "fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261"},
- {file = "fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9"},
- {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c"},
- {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e"},
- {file = "fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5"},
- {file = "fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd"},
- {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3"},
- {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d"},
- {file = "fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c"},
- {file = "fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b"},
- {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd"},
- {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e"},
- {file = "fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c"},
- {file = "fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75"},
- {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063"},
- {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2"},
- {file = "fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c"},
- {file = "fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c"},
- {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa"},
- {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91"},
- {file = "fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19"},
- {file = "fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba"},
- {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7"},
- {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118"},
- {file = "fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5"},
- {file = "fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b"},
- {file = "fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371"},
- {file = "fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69"},
-]
-
-[package.extras]
-all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0) ; python_version <= \"3.14\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"]
-graphite = ["lz4 (>=1.7.4.2)"]
-interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""]
-lxml = ["lxml (>=4.0)"]
-pathops = ["skia-pathops (>=0.5.0)"]
-plot = ["matplotlib"]
-repacker = ["uharfbuzz (>=0.45.0)"]
-symfont = ["sympy"]
-type1 = ["xattr ; sys_platform == \"darwin\""]
-unicode = ["unicodedata2 (>=17.0.0) ; python_version <= \"3.14\""]
-woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"]
-
-[[package]]
-name = "frozenlist"
-version = "1.8.0"
-description = "A list-like structure which implements collections.abc.MutableSequence"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011"},
- {file = "frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565"},
- {file = "frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad"},
- {file = "frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2"},
- {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186"},
- {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e"},
- {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450"},
- {file = "frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef"},
- {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4"},
- {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff"},
- {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c"},
- {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f"},
- {file = "frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7"},
- {file = "frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a"},
- {file = "frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6"},
- {file = "frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e"},
- {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84"},
- {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9"},
- {file = "frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93"},
- {file = "frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f"},
- {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695"},
- {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52"},
- {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581"},
- {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567"},
- {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b"},
- {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92"},
- {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d"},
- {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd"},
- {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967"},
- {file = "frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25"},
- {file = "frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b"},
- {file = "frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a"},
- {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1"},
- {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b"},
- {file = "frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4"},
- {file = "frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383"},
- {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4"},
- {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8"},
- {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b"},
- {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52"},
- {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29"},
- {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3"},
- {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143"},
- {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608"},
- {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa"},
- {file = "frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf"},
- {file = "frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746"},
- {file = "frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd"},
- {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a"},
- {file = "frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7"},
- {file = "frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40"},
- {file = "frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027"},
- {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822"},
- {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121"},
- {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5"},
- {file = "frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e"},
- {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11"},
- {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1"},
- {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1"},
- {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8"},
- {file = "frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed"},
- {file = "frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496"},
- {file = "frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231"},
- {file = "frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62"},
- {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94"},
- {file = "frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c"},
- {file = "frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52"},
- {file = "frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51"},
- {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65"},
- {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82"},
- {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714"},
- {file = "frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d"},
- {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506"},
- {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51"},
- {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e"},
- {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0"},
- {file = "frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41"},
- {file = "frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b"},
- {file = "frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888"},
- {file = "frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042"},
- {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0"},
- {file = "frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f"},
- {file = "frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c"},
- {file = "frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2"},
- {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8"},
- {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686"},
- {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e"},
- {file = "frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a"},
- {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128"},
- {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f"},
- {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7"},
- {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30"},
- {file = "frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7"},
- {file = "frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806"},
- {file = "frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0"},
- {file = "frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b"},
- {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d"},
- {file = "frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed"},
- {file = "frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930"},
- {file = "frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c"},
- {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24"},
- {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37"},
- {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a"},
- {file = "frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2"},
- {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef"},
- {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe"},
- {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8"},
- {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a"},
- {file = "frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e"},
- {file = "frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df"},
- {file = "frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd"},
- {file = "frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79"},
- {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47"},
- {file = "frozenlist-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca"},
- {file = "frozenlist-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068"},
- {file = "frozenlist-1.8.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95"},
- {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459"},
- {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675"},
- {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61"},
- {file = "frozenlist-1.8.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6"},
- {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5"},
- {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3"},
- {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1"},
- {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178"},
- {file = "frozenlist-1.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda"},
- {file = "frozenlist-1.8.0-cp39-cp39-win32.whl", hash = "sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087"},
- {file = "frozenlist-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a"},
- {file = "frozenlist-1.8.0-cp39-cp39-win_arm64.whl", hash = "sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103"},
- {file = "frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d"},
- {file = "frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad"},
-]
-
-[[package]]
-name = "fsspec"
-version = "2025.10.0"
-description = "File-system specification"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "fsspec-2025.10.0-py3-none-any.whl", hash = "sha256:7c7712353ae7d875407f97715f0e1ffcc21e33d5b24556cb1e090ae9409ec61d"},
- {file = "fsspec-2025.10.0.tar.gz", hash = "sha256:b6789427626f068f9a83ca4e8a3cc050850b6c0f71f99ddb4f542b8266a26a59"},
-]
-
-[package.extras]
-abfs = ["adlfs"]
-adl = ["adlfs"]
-arrow = ["pyarrow (>=1)"]
-dask = ["dask", "distributed"]
-dev = ["pre-commit", "ruff (>=0.5)"]
-doc = ["numpydoc", "sphinx", "sphinx-design", "sphinx-rtd-theme", "yarl"]
-dropbox = ["dropbox", "dropboxdrivefs", "requests"]
-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"]
-fuse = ["fusepy"]
-gcs = ["gcsfs"]
-git = ["pygit2"]
-github = ["requests"]
-gs = ["gcsfs"]
-gui = ["panel"]
-hdfs = ["pyarrow (>=1)"]
-http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)"]
-libarchive = ["libarchive-c"]
-oci = ["ocifs"]
-s3 = ["s3fs"]
-sftp = ["paramiko"]
-smb = ["smbprotocol"]
-ssh = ["paramiko"]
-test = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "numpy", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "requests"]
-test-downstream = ["aiobotocore (>=2.5.4,<3.0.0)", "dask[dataframe,test]", "moto[server] (>4,<5)", "pytest-timeout", "xarray"]
-test-full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "cloudpickle", "dask", "distributed", "dropbox", "dropboxdrivefs", "fastparquet", "fusepy", "gcsfs", "jinja2", "kerchunk", "libarchive-c", "lz4", "notebook", "numpy", "ocifs", "pandas", "panel", "paramiko", "pyarrow", "pyarrow (>=1)", "pyftpdlib", "pygit2", "pytest", "pytest-asyncio (!=0.22.0)", "pytest-benchmark", "pytest-cov", "pytest-mock", "pytest-recording", "pytest-rerunfailures", "python-snappy", "requests", "smbprotocol", "tqdm", "urllib3", "zarr", "zstandard ; python_version < \"3.14\""]
-tqdm = ["tqdm"]
-
-[[package]]
-name = "gdown"
-version = "5.2.0"
-description = "Google Drive Public File/Folder Downloader"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "gdown-5.2.0-py3-none-any.whl", hash = "sha256:33083832d82b1101bdd0e9df3edd0fbc0e1c5f14c9d8c38d2a35bf1683b526d6"},
- {file = "gdown-5.2.0.tar.gz", hash = "sha256:2145165062d85520a3cd98b356c9ed522c5e7984d408535409fd46f94defc787"},
-]
-
-[package.dependencies]
-beautifulsoup4 = "*"
-filelock = "*"
-requests = {version = "*", extras = ["socks"]}
-tqdm = "*"
-
-[package.extras]
-test = ["build", "mypy", "pytest", "pytest-xdist", "ruff", "twine", "types-requests", "types-setuptools"]
-
-[[package]]
-name = "gepa"
-version = "0.0.17"
-description = "A framework for optimizing textual system components (AI prompts, code snippets, etc.) using LLM-based reflection and Pareto-efficient evolutionary search."
-optional = false
-python-versions = "<3.14,>=3.10"
-groups = ["dev"]
-files = [
- {file = "gepa-0.0.17-py3-none-any.whl", hash = "sha256:0ea98f4179dbc8dd83bdf53494f302e663ee1da8300d086c4cc8ce4aefa4042c"},
- {file = "gepa-0.0.17.tar.gz", hash = "sha256:641ed46f8127618341b66ee82a87fb46a21c5d2d427a5e0b91c850a7f7f64e7f"},
-]
-
-[package.extras]
-build = ["build", "packaging", "requests", "semver", "setuptools (>=77.0.1)", "twine", "wheel"]
-dev = ["build (>=1.0.3)", "gepa[build]", "gepa[test]", "pre-commit", "ruff (>=0.3.0)"]
-full = ["datasets (>=2.14.6)", "litellm (>=1.64.0)", "mlflow (>=3.0.0)", "tqdm (>=4.66.1)", "wandb"]
-test = ["gepa[full]", "pytest"]
-
-[[package]]
-name = "gevent"
-version = "25.5.1"
-description = "Coroutine-based network library"
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "gevent-25.5.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8e5a0fab5e245b15ec1005b3666b0a2e867c26f411c8fe66ae1afe07174a30e9"},
- {file = "gevent-25.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7b80a37f2fb45ee4a8f7e64b77dd8a842d364384046e394227b974a4e9c9a52"},
- {file = "gevent-25.5.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29ab729d50ae85077a68e0385f129f5b01052d01a0ae6d7fdc1824f5337905e4"},
- {file = "gevent-25.5.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80d20592aeabcc4e294fd441fd43d45cb537437fd642c374ea9d964622fad229"},
- {file = "gevent-25.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8ba0257542ccbb72a8229dc34d00844ccdfba110417e4b7b34599548d0e20e9"},
- {file = "gevent-25.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cad0821dff998c7c60dd238f92cd61380342c47fb9e92e1a8705d9b5ac7c16e8"},
- {file = "gevent-25.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:017a7384c0cd1a5907751c991535a0699596e89725468a7fc39228312e10efa1"},
- {file = "gevent-25.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:469c86d02fccad7e2a3d82fe22237e47ecb376fbf4710bc18747b49c50716817"},
- {file = "gevent-25.5.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:12380aba5c316e9ff53cc21d8ab80f4a91c0df3ada58f65d4f5eb2cf693db00e"},
- {file = "gevent-25.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f0694daab1a041b69a53f53c2141c12994892b2503870515cabe6a5dbd2a928"},
- {file = "gevent-25.5.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2797885e9aeffdc98e1846723e5aa212e7ce53007dbef40d6fd2add264235c41"},
- {file = "gevent-25.5.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cde6aaac36b54332e10ea2a5bc0de6a8aba6c205c92603fe4396e3777c88e05d"},
- {file = "gevent-25.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24484f80f14befb8822bf29554cfb3a26a26cb69cd1e5a8be9e23b4bd7a96e25"},
- {file = "gevent-25.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc7446895fa184890d8ca5ea61e502691114f9db55c9b76adc33f3086c4368"},
- {file = "gevent-25.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5b6106e2414b1797133786258fa1962a5e836480e4d5e861577f9fc63b673a5a"},
- {file = "gevent-25.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:bc899212d90f311784c58938a9c09c59802fb6dc287a35fabdc36d180f57f575"},
- {file = "gevent-25.5.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d87c0a1bd809d8f70f96b9b229779ec6647339830b8888a192beed33ac8d129f"},
- {file = "gevent-25.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b87a4b66edb3808d4d07bbdb0deed5a710cf3d3c531e082759afd283758bb649"},
- {file = "gevent-25.5.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f076779050029a82feb0cb1462021d3404d22f80fa76a181b1a7889cd4d6b519"},
- {file = "gevent-25.5.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bb673eb291c19370f69295f7a881a536451408481e2e3deec3f41dedb7c281ec"},
- {file = "gevent-25.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1325ed44225c8309c0dd188bdbbbee79e1df8c11ceccac226b861c7d52e4837"},
- {file = "gevent-25.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fcd5bcad3102bde686d0adcc341fade6245186050ce14386d547ccab4bd54310"},
- {file = "gevent-25.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1a93062609e8fa67ec97cd5fb9206886774b2a09b24887f40148c9c37e6fb71c"},
- {file = "gevent-25.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:2534c23dc32bed62b659ed4fd9e198906179e68b26c9276a897e04163bdde806"},
- {file = "gevent-25.5.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a022a9de9275ce0b390b7315595454258c525dc8287a03f1a6cacc5878ab7cbc"},
- {file = "gevent-25.5.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fae8533f9d0ef3348a1f503edcfb531ef7a0236b57da1e24339aceb0ce52922"},
- {file = "gevent-25.5.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c7b32d9c3b5294b39ea9060e20c582e49e1ec81edbfeae6cf05f8ad0829cb13d"},
- {file = "gevent-25.5.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b95815fe44f318ebbfd733b6428b4cb18cc5e68f1c40e8501dd69cc1f42a83d"},
- {file = "gevent-25.5.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d316529b70d325b183b2f3f5cde958911ff7be12eb2b532b5c301f915dbbf1e"},
- {file = "gevent-25.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f6ba33c13db91ffdbb489a4f3d177a261ea1843923e1d68a5636c53fe98fa5ce"},
- {file = "gevent-25.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37ee34b77c7553777c0b8379915f75934c3f9c8cd32f7cd098ea43c9323c2276"},
- {file = "gevent-25.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:9fa6aa0da224ed807d3b76cdb4ee8b54d4d4d5e018aed2478098e685baae7896"},
- {file = "gevent-25.5.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:0bacf89a65489d26c7087669af89938d5bfd9f7afb12a07b57855b9fad6ccbd0"},
- {file = "gevent-25.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e30169ef9cc0a57930bfd8fe14d86bc9d39fb96d278e3891e85cbe7b46058a97"},
- {file = "gevent-25.5.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e72ad5f8d9c92df017fb91a1f6a438cfb63b0eff4b40904ff81b40cb8150078c"},
- {file = "gevent-25.5.1-cp39-cp39-win32.whl", hash = "sha256:e5f358e81e27b1a7f2fb2f5219794e13ab5f59ce05571aa3877cfac63adb97db"},
- {file = "gevent-25.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b83aff2441c7d4ee93e519989713b7c2607d4510abe990cd1d04f641bc6c03af"},
- {file = "gevent-25.5.1-pp310-pypy310_pp73-macosx_11_0_universal2.whl", hash = "sha256:60ad4ca9ca2c4cc8201b607c229cd17af749831e371d006d8a91303bb5568eb1"},
- {file = "gevent-25.5.1.tar.gz", hash = "sha256:582c948fa9a23188b890d0bc130734a506d039a2e5ad87dae276a456cc683e61"},
-]
-
-[package.dependencies]
-cffi = {version = ">=1.17.1", markers = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\""}
-greenlet = {version = ">=3.2.2", markers = "platform_python_implementation == \"CPython\""}
-"zope.event" = "*"
-"zope.interface" = "*"
-
-[package.extras]
-dnspython = ["dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\""]
-docs = ["furo", "repoze.sphinx.autointerface", "sphinx", "sphinxcontrib-programoutput", "zope.schema"]
-monitor = ["psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\""]
-recommended = ["cffi (>=1.17.1) ; platform_python_implementation == \"CPython\"", "dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\"", "psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\""]
-test = ["cffi (>=1.17.1) ; platform_python_implementation == \"CPython\"", "coverage (>=5.0) ; sys_platform != \"win32\"", "dnspython (>=1.16.0,<2.0) ; python_version < \"3.10\"", "idna ; python_version < \"3.10\"", "objgraph", "psutil (>=5.7.0) ; sys_platform != \"win32\" or platform_python_implementation == \"CPython\"", "requests"]
-
-[[package]]
-name = "geventhttpclient"
-version = "2.3.5"
-description = "HTTP client library for gevent"
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "geventhttpclient-2.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d38367485cf817a83186fc5bfd39afcf1c5ddfa0808c222ef0e6efda250ed3c3"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d33c4acde33fead6e5a480f972e543508584f133362c5af500400b78fa3561f"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e03f9166a3eb3b63cbc9f6bc30e4fb6f0a6fa9df75fbecffece9d3a151ba0647"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d00c17d780629108c8e3fd4cb2a773eced0353d707b5b61dd3354d0e23d5930e"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e311d1666ccdb3840caa8179cd47457587e96cefda5b6c472d7d7a7432c96d53"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e8ec4b1230341da6cd2f31fcadcb2d9dc7fe68fafbfe687c540e1ee5ddd2310e"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8b54efca12646d4d3cf16fa477ff24b77bd000508184e92366caa275062d115f"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7400970a3aa2d93fedbe7953874e52162963f948a4ae1dbdc434cfbe221e14e5"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8eec18394033ef4e6dfc75b435a8d47d965e9287a8000c770d7aa52081ff860e"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-win32.whl", hash = "sha256:81a8f31be0d5410a14719a50558448e327715f8ad78ccddb9bedc1a6ac2934d4"},
- {file = "geventhttpclient-2.3.5-cp310-cp310-win_amd64.whl", hash = "sha256:773ea06b7604dee5dc54f785eb1cc44e1d5e467d2edf19b01e59f1daf9934051"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a016910b6230ddee56bf6db77473b472100ecd0ab11450ea4918c1058d844355"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:72098f4171e792eddbab72feadd68a3ce443361ce51af254c07eccc9e85000ac"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e22281447d8f04d4f6d55f37c61b5d23d5de1059f1e9c53071c0fe31e58b72f4"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:626a01cfd85aba324bccc9929ebcbb2e3411f03eb8cc3b1c3a2d26614c800999"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7fd15d94d8e0ce835a39ba900721829e5a6c1fc9d48354edb7a10f5e06163c7"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9a2d5d42c9ce3d414fa35639daf280f82b776b8f578024b8478f9a28007bb9d8"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6edda95a0b8f3bf29f5afa38e2e97130da6e3350fa7e1487f9da5540122472f1"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:49fd394265e3815bd0dd034b0aa6fc1f85818660fca63c28d775842036e3eded"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c6de33fdd1de3a94c68b049169908fa13b5b7512ad7d7f6f0fe3427950fccc60"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-win32.whl", hash = "sha256:2c3d93a38123165db876902b526b1222c548e8274b6084a71f9588f58502554b"},
- {file = "geventhttpclient-2.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:cc54c9ff19e0c150bf181972db54fb3e17d278365aaa01d1f5e3842fe846f23e"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c262e295fa017ad7d6d62873e2a781478cb03852b1d0559ccfba598ac059fd23"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:44b822ce5ebddac4cd4ac4199acc2cbec1e968e3bce0ed4c62a4ce8ffaae9277"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e8926ac5338764cabcf8fb54be706a6533d45756f164940a7568b03c80adb1f8"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e84e3985a6a3f9ce39efb8fcfa4273365de2898739eea07d4b259b30ae8d58b7"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:abc63685019c5d6ec08d036248a0743df36e2afa6ab8a1fc833e2a82d0be723f"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:18e129e49ec1dadfb5fc067ac15bd43a3e6f80ddb2b6fd994ce8235c4f8b5e92"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6a04a3bdf102100a14dab58991e984b54e7db9ed950d12d8cb9fdfe5fc5088f0"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3ecaea089408add812a7c1ad9c6043741155f4fbe5ed5c1741ce9322044f419d"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:47fa4d0b9f1739570960b5125e5c86974dff8baaa245d3b96f3e214efbb3ae5e"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-win32.whl", hash = "sha256:677be43d1941543d2897123b98831867a48286c12cd378ad995f545442854558"},
- {file = "geventhttpclient-2.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:cee0ce8bb23668fb6b1a2cc572cb3d01765c5d95734c5d205e1ff459708e4c19"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:700d28d00d77e3c32d9e65dc078ee52a5ca77c3ac16f55674ae36250fe2550a1"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9a0c0d37fc2bc60dea9d66e839c497374a5c15ec45523ae358593c760a5d433e"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c8fceda991eab2afd95c92b3e4177ce684ea8738ef15043ebc911eb7b336dc38"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1fbc86461e993ff6e15ee33a8252bcec6aede03ce8d8640da4205112eba28d11"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e2d8c2b55d2c3e22be8a6fa48acde4771dcdecf01309125f1d8630de8bb4daa"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:006d301f98222d1649b5df7e5b475eefc79519fbaf3309c5fde606db188686c8"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:75bd6b8131e4c566ef69df881f1861e90d00c1222e41ab211f328bec71559d75"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3081221440b270e535cc796b8d3d4e9c423e89a58ac825de94af5a630ea9911e"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee48b9cdde46f4c1e4609f9ba7e4a4096f0447bb5e07ddd531b3bb67461cc4e2"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-win32.whl", hash = "sha256:22b6bd036ce0cfe5e7a280eda17ab6358b7a0f340ed5893015f3d2575624b4a4"},
- {file = "geventhttpclient-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:4d89b59ee8b672b355a598dd2a964b768c1acf9e0c3429bb8e393a9eea31dd26"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:7a5f79c9bd0a47b18e3cf58c27f9aa4e8e13fedb12f20ea494771ad4d721f053"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2e294e70d7c30f0209921dc1548428887923e85f28a78a3905b4a11aefb13746"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c5d8a4a57ecc9281c037544645141514a5753db6d78b2dda014f11ef639cd641"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:18f1a02a1f51731e7433876be07859c8b1ccfd826e79ce7db03a54a1c64c9cb3"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4024739fd05b193b233e084014ee9d87f49cbeb24727d4adf23698417f6fff13"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4cabd19028ccbfa5871d550f627c7b9e163de99f7ad80d451ffcbeee6fb427d9"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:228e639471ed636a7ea46b17fdd207da34f3519e6f84da30b510673ddf2fe2a6"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ac0d3da9228f53f7a4960619172a6b6c11e0b3e8a470903166d83af66bfc8ce6"},
- {file = "geventhttpclient-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d84c96d8b83c5e9b9059e4f2f62917eed834519c00b61d820b2d6aaefb4012a2"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:849bd108028ae0fc24ed65ca8e693c8d4ac140ecffa394e69fc77203c4dd93a2"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:3c412be766aced0bec5d4a7b12a499bc8619a6d692ac2f6df7b8062de26f724b"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:29a8efd438bf13f69bf5099e7577c44fcec8864a832b1de39c484346f0a9bf62"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ab68459780add7b52ada0092af1a4773d0acc870373e6fd21179d9e32d23bfb"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:966ec7a7948adbf2dc5f68d76119d29f05e0c1f645c0d516a5ddb35f9e5d3242"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:693d8fea804cd2547b9cc9bab13c73f9394b912391ab6e34ea3719a1a875e58c"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac03db48b1e0e913b3becd1e5fb2b52453754172be6868e067787f72cd1158ed"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:79e2afab2ec6562bb3814bdac6bb04333f3c6ab4824666565a73f73caf91d8fd"},
- {file = "geventhttpclient-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7803e3e2db5f2bc87743afd015b86b7250c20dc4ace68899b2510a98519d8643"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:200eb7b6f92172dce536fdc5e10e4d97c548bc2827699a33c7c93c9db16f663d"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:04cb387869d8d03dd483d9e1a80021f1d9ee007c9940a8225f1e7a4776a3d6fd"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dd6c87a4bc9955f63c1cb584afaaf188ba8f9d703cb59aefc537e60f9f92347e"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a4eb9d6fc1dd7041a474661a8e658c7cf955077c140f26f435f4bc7d2046c354"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29fb2f816c421daec928c2f288662a16110665d52247524727aff568ca61f418"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ef0b2b1577b9f46314849bc46695bb16c2420e5c8654b37a0d5a58fe62c43a04"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a8f2c1ea6c6e05d92a8b9262b528684a6ff4cf8e910104361eb3d973818417b5"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:8afc2aae3d4f41d075edd17cf276c786921e24317d0d6013dbca4e7b2d982251"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:cd0b558880731d28e4344a988ef507e836281c6b7f97cadfbe567d4337e9d01d"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-win32.whl", hash = "sha256:bedce686419a3c00acb2ccfba2ba39d7636aef61dea1c8d2fe7604c78cd9b1b1"},
- {file = "geventhttpclient-2.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:4d5c51fd142ffbddc218d83a62c8ca493312d5d215d8cd490288ec4f2668a9ca"},
- {file = "geventhttpclient-2.3.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d0798ae0f576e0153479a1a051f2cf0611cfcf63776d5d5c605da32a4ce728ce"},
- {file = "geventhttpclient-2.3.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cbdba8426ec9c4cf36ca8687695c53fcd4024d994f409a8ff8724c2a23292164"},
- {file = "geventhttpclient-2.3.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e0703130cb307bf1f299dd54f4476a2dbef87f0e209a9f7d9a0924c159fd9a3f"},
- {file = "geventhttpclient-2.3.5.tar.gz", hash = "sha256:0f0cf13528de7628a21b28b80ee90a471d4840e3fe26f84b394644c366595151"},
-]
-
-[package.dependencies]
-brotli = "*"
-certifi = "*"
-gevent = "*"
-urllib3 = "*"
-
-[package.extras]
-benchmarks = ["httplib2", "httpx", "requests", "urllib3"]
-dev = ["dpkt", "pytest", "requests"]
-examples = ["oauth2"]
-
-[[package]]
-name = "gitdb"
-version = "4.0.12"
-description = "Git Object Database"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev", "eval"]
-files = [
- {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"},
- {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"},
-]
-
-[package.dependencies]
-smmap = ">=3.0.1,<6"
-
-[[package]]
-name = "gitpython"
-version = "3.1.45"
-description = "GitPython is a Python library used to interact with Git repositories"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev", "eval"]
-files = [
- {file = "gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77"},
- {file = "gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c"},
-]
-
-[package.dependencies]
-gitdb = ">=4.0.1,<5"
-
-[package.extras]
-doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"]
-test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock ; python_version < \"3.8\"", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions ; python_version < \"3.11\""]
-
-[[package]]
-name = "google-auth"
-version = "2.43.0"
-description = "Google Authentication Library"
-optional = false
-python-versions = ">=3.7"
-groups = ["main"]
-files = [
- {file = "google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16"},
- {file = "google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483"},
-]
-
-[package.dependencies]
-cachetools = ">=2.0.0,<7.0"
-pyasn1-modules = ">=0.2.1"
-rsa = ">=3.1.4,<5"
-
-[package.extras]
-aiohttp = ["aiohttp (>=3.6.2,<4.0.0)", "requests (>=2.20.0,<3.0.0)"]
-enterprise-cert = ["cryptography", "pyopenssl"]
-pyjwt = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyjwt (>=2.0)"]
-pyopenssl = ["cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"]
-reauth = ["pyu2f (>=0.1.5)"]
-requests = ["requests (>=2.20.0,<3.0.0)"]
-testing = ["aiohttp (<3.10.0)", "aiohttp (>=3.6.2,<4.0.0)", "aioresponses", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (<39.0.0) ; python_version < \"3.8\"", "cryptography (>=38.0.3)", "cryptography (>=38.0.3)", "flask", "freezegun", "grpcio", "mock", "oauth2client", "packaging", "pyjwt (>=2.0)", "pyopenssl (<24.3.0)", "pyopenssl (>=20.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-localserver", "pyu2f (>=0.1.5)", "requests (>=2.20.0,<3.0.0)", "responses", "urllib3"]
-urllib3 = ["packaging", "urllib3"]
-
-[[package]]
-name = "greenlet"
-version = "3.2.4"
-description = "Lightweight in-process concurrent programming"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "test"]
-files = [
- {file = "greenlet-3.2.4-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:8c68325b0d0acf8d91dde4e6f930967dd52a5302cd4062932a6b2e7c2969f47c"},
- {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:94385f101946790ae13da500603491f04a76b6e4c059dab271b3ce2e283b2590"},
- {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f10fd42b5ee276335863712fa3da6608e93f70629c631bf77145021600abc23c"},
- {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c8c9e331e58180d0d83c5b7999255721b725913ff6bc6cf39fa2a45841a4fd4b"},
- {file = "greenlet-3.2.4-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58b97143c9cc7b86fc458f215bd0932f1757ce649e05b640fea2e79b54cedb31"},
- {file = "greenlet-3.2.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2ca18a03a8cfb5b25bc1cbe20f3d9a4c80d8c3b13ba3df49ac3961af0b1018d"},
- {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9fe0a28a7b952a21e2c062cd5756d34354117796c6d9215a87f55e38d15402c5"},
- {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8854167e06950ca75b898b104b63cc646573aa5fef1353d4508ecdd1ee76254f"},
- {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f47617f698838ba98f4ff4189aef02e7343952df3a615f847bb575c3feb177a7"},
- {file = "greenlet-3.2.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af41be48a4f60429d5cad9d22175217805098a9ef7c40bfef44f7669fb9d74d8"},
- {file = "greenlet-3.2.4-cp310-cp310-win_amd64.whl", hash = "sha256:73f49b5368b5359d04e18d15828eecc1806033db5233397748f4ca813ff1056c"},
- {file = "greenlet-3.2.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:96378df1de302bc38e99c3a9aa311967b7dc80ced1dcc6f171e99842987882a2"},
- {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1ee8fae0519a337f2329cb78bd7a8e128ec0f881073d43f023c7b8d4831d5246"},
- {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94abf90142c2a18151632371140b3dba4dee031633fe614cb592dbb6c9e17bc3"},
- {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:4d1378601b85e2e5171b99be8d2dc85f594c79967599328f95c1dc1a40f1c633"},
- {file = "greenlet-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0db5594dce18db94f7d1650d7489909b57afde4c580806b8d9203b6e79cdc079"},
- {file = "greenlet-3.2.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2523e5246274f54fdadbce8494458a2ebdcdbc7b802318466ac5606d3cded1f8"},
- {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1987de92fec508535687fb807a5cea1560f6196285a4cde35c100b8cd632cc52"},
- {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:55e9c5affaa6775e2c6b67659f3a71684de4c549b3dd9afca3bc773533d284fa"},
- {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9c6de1940a7d828635fbd254d69db79e54619f165ee7ce32fda763a9cb6a58c"},
- {file = "greenlet-3.2.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03c5136e7be905045160b1b9fdca93dd6727b180feeafda6818e6496434ed8c5"},
- {file = "greenlet-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:9c40adce87eaa9ddb593ccb0fa6a07caf34015a29bf8d344811665b573138db9"},
- {file = "greenlet-3.2.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3b67ca49f54cede0186854a008109d6ee71f66bd57bb36abd6d0a0267b540cdd"},
- {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ddf9164e7a5b08e9d22511526865780a576f19ddd00d62f8a665949327fde8bb"},
- {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f28588772bb5fb869a8eb331374ec06f24a83a9c25bfa1f38b6993afe9c1e968"},
- {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5c9320971821a7cb77cfab8d956fa8e39cd07ca44b6070db358ceb7f8797c8c9"},
- {file = "greenlet-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c60a6d84229b271d44b70fb6e5fa23781abb5d742af7b808ae3f6efd7c9c60f6"},
- {file = "greenlet-3.2.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b3812d8d0c9579967815af437d96623f45c0f2ae5f04e366de62a12d83a8fb0"},
- {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:abbf57b5a870d30c4675928c37278493044d7c14378350b3aa5d484fa65575f0"},
- {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:20fb936b4652b6e307b8f347665e2c615540d4b42b3b4c8a321d8286da7e520f"},
- {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee7a6ec486883397d70eec05059353b8e83eca9168b9f3f9a361971e77e0bcd0"},
- {file = "greenlet-3.2.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:326d234cbf337c9c3def0676412eb7040a35a768efc92504b947b3e9cfc7543d"},
- {file = "greenlet-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:a7d4e128405eea3814a12cc2605e0e6aedb4035bf32697f72deca74de4105e02"},
- {file = "greenlet-3.2.4-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:1a921e542453fe531144e91e1feedf12e07351b1cf6c9e8a3325ea600a715a31"},
- {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd3c8e693bff0fff6ba55f140bf390fa92c994083f838fece0f63be121334945"},
- {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:710638eb93b1fa52823aa91bf75326f9ecdfd5e0466f00789246a5280f4ba0fc"},
- {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:c5111ccdc9c88f423426df3fd1811bfc40ed66264d35aa373420a34377efc98a"},
- {file = "greenlet-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76383238584e9711e20ebe14db6c88ddcedc1829a9ad31a584389463b5aa504"},
- {file = "greenlet-3.2.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23768528f2911bcd7e475210822ffb5254ed10d71f4028387e5a99b4c6699671"},
- {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:00fadb3fedccc447f517ee0d3fd8fe49eae949e1cd0f6a611818f4f6fb7dc83b"},
- {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d25c5091190f2dc0eaa3f950252122edbbadbb682aa7b1ef2f8af0f8c0afefae"},
- {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e343822feb58ac4d0a1211bd9399de2b3a04963ddeec21530fc426cc121f19b"},
- {file = "greenlet-3.2.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca7f6f1f2649b89ce02f6f229d7c19f680a6238af656f61e0115b24857917929"},
- {file = "greenlet-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:554b03b6e73aaabec3745364d6239e9e012d64c68ccd0b8430c64ccc14939a8b"},
- {file = "greenlet-3.2.4-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:49a30d5fda2507ae77be16479bdb62a660fa51b1eb4928b524975b3bde77b3c0"},
- {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:299fd615cd8fc86267b47597123e3f43ad79c9d8a22bebdce535e53550763e2f"},
- {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:c17b6b34111ea72fc5a4e4beec9711d2226285f0386ea83477cbb97c30a3f3a5"},
- {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b4a1870c51720687af7fa3e7cda6d08d801dae660f75a76f3845b642b4da6ee1"},
- {file = "greenlet-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:061dc4cf2c34852b052a8620d40f36324554bc192be474b9e9770e8c042fd735"},
- {file = "greenlet-3.2.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:44358b9bf66c8576a9f57a590d5f5d6e72fa4228b763d0e43fee6d3b06d3a337"},
- {file = "greenlet-3.2.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2917bdf657f5859fbf3386b12d68ede4cf1f04c90c3a6bc1f013dd68a22e2269"},
- {file = "greenlet-3.2.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:015d48959d4add5d6c9f6c5210ee3803a830dce46356e3bc326d6776bde54681"},
- {file = "greenlet-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:e37ab26028f12dbb0ff65f29a8d3d44a765c61e729647bf2ddfbbed621726f01"},
- {file = "greenlet-3.2.4-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:b6a7c19cf0d2742d0809a4c05975db036fdff50cd294a93632d6a310bf9ac02c"},
- {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:27890167f55d2387576d1f41d9487ef171849ea0359ce1510ca6e06c8bece11d"},
- {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:18d9260df2b5fbf41ae5139e1be4e796d99655f023a636cd0e11e6406cca7d58"},
- {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:671df96c1f23c4a0d4077a325483c1503c96a1b7d9db26592ae770daa41233d4"},
- {file = "greenlet-3.2.4-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:16458c245a38991aa19676900d48bd1a6f2ce3e16595051a4db9d012154e8433"},
- {file = "greenlet-3.2.4-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9913f1a30e4526f432991f89ae263459b1c64d1608c0d22a5c79c287b3c70df"},
- {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b90654e092f928f110e0007f572007c9727b5265f7632c2fa7415b4689351594"},
- {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:81701fd84f26330f0d5f4944d4e92e61afe6319dcd9775e39396e39d7c3e5f98"},
- {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:28a3c6b7cd72a96f61b0e4b2a36f681025b60ae4779cc73c1535eb5f29560b10"},
- {file = "greenlet-3.2.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:52206cd642670b0b320a1fd1cbfd95bca0e043179c1d8a045f2c6109dfe973be"},
- {file = "greenlet-3.2.4-cp39-cp39-win32.whl", hash = "sha256:65458b409c1ed459ea899e939f0e1cdb14f58dbc803f2f93c5eab5694d32671b"},
- {file = "greenlet-3.2.4-cp39-cp39-win_amd64.whl", hash = "sha256:d2e685ade4dafd447ede19c31277a224a239a0a1a4eca4e6390efedf20260cfb"},
- {file = "greenlet-3.2.4.tar.gz", hash = "sha256:0dca0d95ff849f9a364385f36ab49f50065d76964944638be9691e1832e9f86d"},
-]
-markers = {dev = "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\"", test = "platform_python_implementation == \"CPython\""}
-
-[package.extras]
-docs = ["Sphinx", "furo"]
-test = ["objgraph", "psutil", "setuptools"]
-
-[[package]]
-name = "grpcio"
-version = "1.78.0"
-description = "HTTP/2-based RPC framework"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "grpcio-1.78.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:7cc47943d524ee0096f973e1081cb8f4f17a4615f2116882a5f1416e4cfe92b5"},
- {file = "grpcio-1.78.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c3f293fdc675ccba4db5a561048cca627b5e7bd1c8a6973ffedabe7d116e22e2"},
- {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10a9a644b5dd5aec3b82b5b0b90d41c0fa94c85ef42cb42cf78a23291ddb5e7d"},
- {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4c5533d03a6cbd7f56acfc9cfb44ea64f63d29091e40e44010d34178d392d7eb"},
- {file = "grpcio-1.78.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ff870aebe9a93a85283837801d35cd5f8814fe2ad01e606861a7fb47c762a2b7"},
- {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:391e93548644e6b2726f1bb84ed60048d4bcc424ce5e4af0843d28ca0b754fec"},
- {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:df2c8f3141f7cbd112a6ebbd760290b5849cda01884554f7c67acc14e7b1758a"},
- {file = "grpcio-1.78.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd8cb8026e5f5b50498a3c4f196f57f9db344dad829ffae16b82e4fdbaea2813"},
- {file = "grpcio-1.78.0-cp310-cp310-win32.whl", hash = "sha256:f8dff3d9777e5d2703a962ee5c286c239bf0ba173877cc68dc02c17d042e29de"},
- {file = "grpcio-1.78.0-cp310-cp310-win_amd64.whl", hash = "sha256:94f95cf5d532d0e717eed4fc1810e8e6eded04621342ec54c89a7c2f14b581bf"},
- {file = "grpcio-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2777b783f6c13b92bd7b716667452c329eefd646bfb3f2e9dabea2e05dbd34f6"},
- {file = "grpcio-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:9dca934f24c732750389ce49d638069c3892ad065df86cb465b3fa3012b70c9e"},
- {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:459ab414b35f4496138d0ecd735fed26f1318af5e52cb1efbc82a09f0d5aa911"},
- {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:082653eecbdf290e6e3e2c276ab2c54b9e7c299e07f4221872380312d8cf395e"},
- {file = "grpcio-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85f93781028ec63f383f6bc90db785a016319c561cc11151fbb7b34e0d012303"},
- {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f12857d24d98441af6a1d5c87442d624411db486f7ba12550b07788f74b67b04"},
- {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5397fff416b79e4b284959642a4e95ac4b0f1ece82c9993658e0e477d40551ec"},
- {file = "grpcio-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbe6e89c7ffb48518384068321621b2a69cab509f58e40e4399fdd378fa6d074"},
- {file = "grpcio-1.78.0-cp311-cp311-win32.whl", hash = "sha256:6092beabe1966a3229f599d7088b38dfc8ffa1608b5b5cdda31e591e6500f856"},
- {file = "grpcio-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:1afa62af6e23f88629f2b29ec9e52ec7c65a7176c1e0a83292b93c76ca882558"},
- {file = "grpcio-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f9ab915a267fc47c7e88c387a3a28325b58c898e23d4995f765728f4e3dedb97"},
- {file = "grpcio-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3f8904a8165ab21e07e58bf3e30a73f4dffc7a1e0dbc32d51c61b5360d26f43e"},
- {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:859b13906ce098c0b493af92142ad051bf64c7870fa58a123911c88606714996"},
- {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b2342d87af32790f934a79c3112641e7b27d63c261b8b4395350dad43eff1dc7"},
- {file = "grpcio-1.78.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12a771591ae40bc65ba67048fa52ef4f0e6db8279e595fd349f9dfddeef571f9"},
- {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:185dea0d5260cbb2d224c507bf2a5444d5abbb1fa3594c1ed7e4c709d5eb8383"},
- {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:51b13f9aed9d59ee389ad666b8c2214cc87b5de258fa712f9ab05f922e3896c6"},
- {file = "grpcio-1.78.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fd5f135b1bd58ab088930b3c613455796dfa0393626a6972663ccdda5b4ac6ce"},
- {file = "grpcio-1.78.0-cp312-cp312-win32.whl", hash = "sha256:94309f498bcc07e5a7d16089ab984d42ad96af1d94b5a4eb966a266d9fcabf68"},
- {file = "grpcio-1.78.0-cp312-cp312-win_amd64.whl", hash = "sha256:9566fe4ababbb2610c39190791e5b829869351d14369603702e890ef3ad2d06e"},
- {file = "grpcio-1.78.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:ce3a90455492bf8bfa38e56fbbe1dbd4f872a3d8eeaf7337dc3b1c8aa28c271b"},
- {file = "grpcio-1.78.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:2bf5e2e163b356978b23652c4818ce4759d40f4712ee9ec5a83c4be6f8c23a3a"},
- {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8f2ac84905d12918e4e55a16da17939eb63e433dc11b677267c35568aa63fc84"},
- {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b58f37edab4a3881bc6c9bca52670610e0c9ca14e2ea3cf9debf185b870457fb"},
- {file = "grpcio-1.78.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:735e38e176a88ce41840c21bb49098ab66177c64c82426e24e0082500cc68af5"},
- {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2045397e63a7a0ee7957c25f7dbb36ddc110e0cfb418403d110c0a7a68a844e9"},
- {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9f136fbafe7ccf4ac7e8e0c28b31066e810be52d6e344ef954a3a70234e1702"},
- {file = "grpcio-1.78.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:748b6138585379c737adc08aeffd21222abbda1a86a0dca2a39682feb9196c20"},
- {file = "grpcio-1.78.0-cp313-cp313-win32.whl", hash = "sha256:271c73e6e5676afe4fc52907686670c7cea22ab2310b76a59b678403ed40d670"},
- {file = "grpcio-1.78.0-cp313-cp313-win_amd64.whl", hash = "sha256:f2d4e43ee362adfc05994ed479334d5a451ab7bc3f3fee1b796b8ca66895acb4"},
- {file = "grpcio-1.78.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:e87cbc002b6f440482b3519e36e1313eb5443e9e9e73d6a52d43bd2004fcfd8e"},
- {file = "grpcio-1.78.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:c41bc64626db62e72afec66b0c8a0da76491510015417c127bfc53b2fe6d7f7f"},
- {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8dfffba826efcf366b1e3ccc37e67afe676f290e13a3b48d31a46739f80a8724"},
- {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:74be1268d1439eaaf552c698cdb11cd594f0c49295ae6bb72c34ee31abbe611b"},
- {file = "grpcio-1.78.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be63c88b32e6c0f1429f1398ca5c09bc64b0d80950c8bb7807d7d7fb36fb84c7"},
- {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:3c586ac70e855c721bda8f548d38c3ca66ac791dc49b66a8281a1f99db85e452"},
- {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:35eb275bf1751d2ffbd8f57cdbc46058e857cf3971041521b78b7db94bdaf127"},
- {file = "grpcio-1.78.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:207db540302c884b8848036b80db352a832b99dfdf41db1eb554c2c2c7800f65"},
- {file = "grpcio-1.78.0-cp314-cp314-win32.whl", hash = "sha256:57bab6deef2f4f1ca76cc04565df38dc5713ae6c17de690721bdf30cb1e0545c"},
- {file = "grpcio-1.78.0-cp314-cp314-win_amd64.whl", hash = "sha256:dce09d6116df20a96acfdbf85e4866258c3758180e8c49845d6ba8248b6d0bbb"},
- {file = "grpcio-1.78.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:86f85dd7c947baa707078a236288a289044836d4b640962018ceb9cd1f899af5"},
- {file = "grpcio-1.78.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:de8cb00d1483a412a06394b8303feec5dcb3b55f81d83aa216dbb6a0b86a94f5"},
- {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e888474dee2f59ff68130f8a397792d8cb8e17e6b3434339657ba4ee90845a8c"},
- {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:86ce2371bfd7f212cf60d8517e5e854475c2c43ce14aa910e136ace72c6db6c1"},
- {file = "grpcio-1.78.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0c689c02947d636bc7fab3e30cc3a3445cca99c834dfb77cd4a6cabfc1c5597"},
- {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ce7599575eeb25c0f4dc1be59cada6219f3b56176f799627f44088b21381a28a"},
- {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:684083fd383e9dc04c794adb838d4faea08b291ce81f64ecd08e4577c7398adf"},
- {file = "grpcio-1.78.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ab399ef5e3cd2a721b1038a0f3021001f19c5ab279f145e1146bb0b9f1b2b12c"},
- {file = "grpcio-1.78.0-cp39-cp39-win32.whl", hash = "sha256:f3d6379493e18ad4d39537a82371c5281e153e963cecb13f953ebac155756525"},
- {file = "grpcio-1.78.0-cp39-cp39-win_amd64.whl", hash = "sha256:5361a0630a7fdb58a6a97638ab70e1dae2893c4d08d7aba64ded28bb9e7a29df"},
- {file = "grpcio-1.78.0.tar.gz", hash = "sha256:7382b95189546f375c174f53a5fa873cef91c4b8005faa05cc5b3beea9c4f1c5"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.12,<5.0"
-
-[package.extras]
-protobuf = ["grpcio-tools (>=1.78.0)"]
-
-[[package]]
-name = "h11"
-version = "0.16.0"
-description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "test"]
-files = [
- {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
- {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"},
-]
-
-[[package]]
-name = "h2"
-version = "4.3.0"
-description = "Pure-Python HTTP/2 protocol implementation"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd"},
- {file = "h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1"},
-]
-
-[package.dependencies]
-hpack = ">=4.1,<5"
-hyperframe = ">=6.1,<7"
-
-[[package]]
-name = "haystack-ai"
-version = "2.7.0"
-description = "LLM framework to build customizable, production-ready LLM applications. Connect components (models, vector DBs, file converters) to pipelines or agents that can interact with your data."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "haystack_ai-2.7.0-py3-none-any.whl", hash = "sha256:9226fb099403ed676a7fee908a0c0dd6435d52bc5a092c867c34958333a0d358"},
- {file = "haystack_ai-2.7.0.tar.gz", hash = "sha256:b950bbba229c3cb036cf4db1726bea8c8d1ca8c8b7a9afe27225394e55c6ba65"},
-]
-
-[package.dependencies]
-haystack-experimental = "*"
-jinja2 = "*"
-lazy-imports = "*"
-more-itertools = "*"
-networkx = "*"
-numpy = "*"
-openai = ">=1.1.0"
-pandas = "*"
-posthog = "*"
-python-dateutil = "*"
-pyyaml = "*"
-requests = "*"
-tenacity = "!=8.4.0"
-tqdm = "*"
-typing-extensions = ">=4.7"
-
-[[package]]
-name = "haystack-experimental"
-version = "0.14.2"
-description = "Experimental components and features for the Haystack LLM framework."
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "haystack_experimental-0.14.2-py3-none-any.whl", hash = "sha256:273f113e1a02c07ea3e15fffc43cd744226526fa32f843824e25373ea9b63fd2"},
- {file = "haystack_experimental-0.14.2.tar.gz", hash = "sha256:f2a2f90e695deaefecc312ad736ea5ea18baca02d6441f5f3ded117916756d5b"},
-]
-
-[package.dependencies]
-haystack-ai = "*"
-rich = "*"
-
-[[package]]
-name = "hf-xet"
-version = "1.2.0"
-description = "Fast transfer of large files with the Hugging Face Hub."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-markers = "platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"arm64\" or platform_machine == \"aarch64\""
-files = [
- {file = "hf_xet-1.2.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649"},
- {file = "hf_xet-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813"},
- {file = "hf_xet-1.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc"},
- {file = "hf_xet-1.2.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5"},
- {file = "hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f"},
- {file = "hf_xet-1.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832"},
- {file = "hf_xet-1.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382"},
- {file = "hf_xet-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e"},
- {file = "hf_xet-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8"},
- {file = "hf_xet-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0"},
- {file = "hf_xet-1.2.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090"},
- {file = "hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a"},
- {file = "hf_xet-1.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f"},
- {file = "hf_xet-1.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc"},
- {file = "hf_xet-1.2.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848"},
- {file = "hf_xet-1.2.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4"},
- {file = "hf_xet-1.2.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd"},
- {file = "hf_xet-1.2.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c"},
- {file = "hf_xet-1.2.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737"},
- {file = "hf_xet-1.2.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865"},
- {file = "hf_xet-1.2.0-cp37-abi3-win_amd64.whl", hash = "sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69"},
- {file = "hf_xet-1.2.0.tar.gz", hash = "sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f"},
-]
-
-[package.extras]
-tests = ["pytest"]
-
-[[package]]
-name = "hpack"
-version = "4.1.0"
-description = "Pure-Python HPACK header encoding"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496"},
- {file = "hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"},
-]
-
-[[package]]
-name = "httpcore"
-version = "1.0.9"
-description = "A minimal low-level HTTP client."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
- {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"},
-]
-
-[package.dependencies]
-certifi = "*"
-h11 = ">=0.16"
-
-[package.extras]
-asyncio = ["anyio (>=4.0,<5.0)"]
-http2 = ["h2 (>=3,<5)"]
-socks = ["socksio (==1.*)"]
-trio = ["trio (>=0.22.0,<1.0)"]
-
-[[package]]
-name = "httptools"
-version = "0.7.1"
-description = "A collection of framework independent HTTP protocol utils."
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "httptools-0.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78"},
- {file = "httptools-0.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4"},
- {file = "httptools-0.7.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05"},
- {file = "httptools-0.7.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed"},
- {file = "httptools-0.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a"},
- {file = "httptools-0.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b"},
- {file = "httptools-0.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568"},
- {file = "httptools-0.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657"},
- {file = "httptools-0.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70"},
- {file = "httptools-0.7.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df"},
- {file = "httptools-0.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e"},
- {file = "httptools-0.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274"},
- {file = "httptools-0.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec"},
- {file = "httptools-0.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb"},
- {file = "httptools-0.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5"},
- {file = "httptools-0.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5"},
- {file = "httptools-0.7.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03"},
- {file = "httptools-0.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2"},
- {file = "httptools-0.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362"},
- {file = "httptools-0.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c"},
- {file = "httptools-0.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321"},
- {file = "httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3"},
- {file = "httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca"},
- {file = "httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c"},
- {file = "httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66"},
- {file = "httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346"},
- {file = "httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650"},
- {file = "httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6"},
- {file = "httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270"},
- {file = "httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3"},
- {file = "httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1"},
- {file = "httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b"},
- {file = "httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60"},
- {file = "httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca"},
- {file = "httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96"},
- {file = "httptools-0.7.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4"},
- {file = "httptools-0.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a"},
- {file = "httptools-0.7.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf"},
- {file = "httptools-0.7.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28"},
- {file = "httptools-0.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517"},
- {file = "httptools-0.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad"},
- {file = "httptools-0.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023"},
- {file = "httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9"},
-]
-
-[[package]]
-name = "httpx"
-version = "0.28.1"
-description = "The next generation HTTP client."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
- {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"},
-]
-
-[package.dependencies]
-anyio = "*"
-certifi = "*"
-h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""}
-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 = "huggingface-hub"
-version = "1.1.2"
-description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub"
-optional = false
-python-versions = ">=3.9.0"
-groups = ["main", "dev"]
-files = [
- {file = "huggingface_hub-1.1.2-py3-none-any.whl", hash = "sha256:dfcfa84a043466fac60573c3e4af475490a7b0d7375b22e3817706d6659f61f7"},
- {file = "huggingface_hub-1.1.2.tar.gz", hash = "sha256:7bdafc432dc12fa1f15211bdfa689a02531d2a47a3cc0d74935f5726cdbcab8e"},
-]
-
-[package.dependencies]
-filelock = "*"
-fsspec = ">=2023.5.0"
-hf-xet = {version = ">=1.2.0,<2.0.0", markers = "platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"arm64\" or platform_machine == \"aarch64\""}
-httpx = ">=0.23.0,<1"
-packaging = ">=20.9"
-pyyaml = ">=5.1"
-shellingham = "*"
-tqdm = ">=4.42.1"
-typer-slim = "*"
-typing-extensions = ">=3.7.4.3"
-
-[package.extras]
-all = ["Jinja2", "Pillow", "authlib (>=1.3.2)", "fastapi", "fastapi", "httpx", "itsdangerous", "jedi", "libcst (>=1.4.0)", "mypy (==1.15.0)", "numpy", "pytest (>=8.4.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "ty", "types-PyYAML", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
-dev = ["Jinja2", "Pillow", "authlib (>=1.3.2)", "fastapi", "fastapi", "httpx", "itsdangerous", "jedi", "libcst (>=1.4.0)", "mypy (==1.15.0)", "numpy", "pytest (>=8.4.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "ruff (>=0.9.0)", "soundfile", "ty", "types-PyYAML", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"]
-fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"]
-hf-xet = ["hf-xet (>=1.1.3,<2.0.0)"]
-mcp = ["mcp (>=1.8.0)"]
-oauth = ["authlib (>=1.3.2)", "fastapi", "httpx", "itsdangerous"]
-quality = ["libcst (>=1.4.0)", "mypy (==1.15.0)", "ruff (>=0.9.0)", "ty"]
-testing = ["Jinja2", "Pillow", "authlib (>=1.3.2)", "fastapi", "fastapi", "httpx", "itsdangerous", "jedi", "numpy", "pytest (>=8.4.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures (<16.0)", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"]
-torch = ["safetensors[torch]", "torch"]
-typing = ["types-PyYAML", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"]
-
-[[package]]
-name = "hyperframe"
-version = "6.1.0"
-description = "Pure-Python HTTP/2 framing"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5"},
- {file = "hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"},
-]
-
-[[package]]
-name = "identify"
-version = "2.6.15"
-description = "File identification library for Python"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757"},
- {file = "identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf"},
-]
-
-[package.extras]
-license = ["ukkonen"]
-
-[[package]]
-name = "idna"
-version = "3.11"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"},
- {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"},
-]
-
-[package.extras]
-all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
-
-[[package]]
-name = "importlib-metadata"
-version = "8.5.0"
-description = "Read metadata from Python packages"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"},
- {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"},
-]
-
-[package.dependencies]
-zipp = ">=3.20"
-
-[package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
-cover = ["pytest-cov"]
-doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-enabler = ["pytest-enabler (>=2.2)"]
-perf = ["ipython"]
-test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"]
-type = ["pytest-mypy"]
-
-[[package]]
-name = "iniconfig"
-version = "2.3.0"
-description = "brain-dead simple config-ini parsing"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev", "test"]
-files = [
- {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"},
- {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"},
-]
-
-[[package]]
-name = "ipykernel"
-version = "6.31.0"
-description = "IPython Kernel for Jupyter"
-optional = false
-python-versions = ">=3.9"
-groups = ["eval"]
-files = [
- {file = "ipykernel-6.31.0-py3-none-any.whl", hash = "sha256:abe5386f6ced727a70e0eb0cf1da801fa7c5fa6ff82147747d5a0406cd8c94af"},
- {file = "ipykernel-6.31.0.tar.gz", hash = "sha256:2372ce8bc1ff4f34e58cafed3a0feb2194b91fc7cad0fc72e79e47b45ee9e8f6"},
-]
-
-[package.dependencies]
-appnope = {version = ">=0.1.2", markers = "platform_system == \"Darwin\""}
-comm = ">=0.1.1"
-debugpy = ">=1.6.5"
-ipython = ">=7.23.1"
-jupyter-client = ">=8.0.0"
-jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
-matplotlib-inline = ">=0.1"
-nest-asyncio = ">=1.4"
-packaging = ">=22"
-psutil = ">=5.7"
-pyzmq = ">=25"
-tornado = ">=6.2"
-traitlets = ">=5.4.0"
-
-[package.extras]
-cov = ["coverage[toml]", "matplotlib", "pytest-cov", "trio"]
-docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"]
-pyqt5 = ["pyqt5"]
-pyside6 = ["pyside6"]
-test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0,<9)", "pytest-asyncio (>=0.23.5)", "pytest-cov", "pytest-timeout"]
-
-[[package]]
-name = "ipython"
-version = "9.7.0"
-description = "IPython: Productive Interactive Computing"
-optional = false
-python-versions = ">=3.11"
-groups = ["eval"]
-files = [
- {file = "ipython-9.7.0-py3-none-any.whl", hash = "sha256:bce8ac85eb9521adc94e1845b4c03d88365fd6ac2f4908ec4ed1eb1b0a065f9f"},
- {file = "ipython-9.7.0.tar.gz", hash = "sha256:5f6de88c905a566c6a9d6c400a8fed54a638e1f7543d17aae2551133216b1e4e"},
-]
-
-[package.dependencies]
-colorama = {version = ">=0.4.4", markers = "sys_platform == \"win32\""}
-decorator = ">=4.3.2"
-ipython-pygments-lexers = ">=1.0.0"
-jedi = ">=0.18.1"
-matplotlib-inline = ">=0.1.5"
-pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""}
-prompt_toolkit = ">=3.0.41,<3.1.0"
-pygments = ">=2.11.0"
-stack_data = ">=0.6.0"
-traitlets = ">=5.13.0"
-
-[package.extras]
-all = ["ipython[doc,matplotlib,test,test-extra]"]
-black = ["black"]
-doc = ["docrepr", "exceptiongroup", "intersphinx_registry", "ipykernel", "ipython[matplotlib,test]", "setuptools (>=70.0)", "sphinx (>=8.0)", "sphinx-rtd-theme (>=0.1.8)", "sphinx_toml (==0.0.4)", "typing_extensions"]
-matplotlib = ["matplotlib (>3.9)"]
-test = ["packaging (>=20.1.0)", "pytest (>=7.0.0)", "pytest-asyncio (>=1.0.0)", "setuptools (>=61.2)", "testpath (>=0.2)"]
-test-extra = ["curio", "ipykernel (>6.30)", "ipython[matplotlib]", "ipython[test]", "jupyter_ai", "nbclient", "nbformat", "numpy (>=1.27)", "pandas (>2.1)", "trio (>=0.1.0)"]
-
-[[package]]
-name = "ipython-pygments-lexers"
-version = "1.1.1"
-description = "Defines a variety of Pygments lexers for highlighting IPython code."
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c"},
- {file = "ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81"},
-]
-
-[package.dependencies]
-pygments = "*"
-
-[[package]]
-name = "itables"
-version = "2.5.2"
-description = "Pandas and Polar DataFrames as interactive DataTables"
-optional = false
-python-versions = ">=3.9"
-groups = ["eval"]
-files = [
- {file = "itables-2.5.2-py3-none-any.whl", hash = "sha256:a26b5a5fad079db7eee83ff720fb98395f7327fddcb7af84d10e1165a139acf2"},
- {file = "itables-2.5.2.tar.gz", hash = "sha256:ec34bbacfbf4305570ea75b36970de442f924126f3701c323a5a46018de84c8a"},
-]
-
-[package.dependencies]
-ipython = "*"
-numpy = "*"
-pandas = "*"
-
-[package.extras]
-all = ["anywidget", "dash", "matplotlib", "platformdirs", "polars", "pyarrow", "pytz", "shiny", "shinywidgets", "streamlit", "tomli ; python_version < \"3.11\"", "traitlets", "typeguard (>=4.4.1)", "world-bank-data"]
-check-type = ["typeguard (>=4.4.1)"]
-config = ["platformdirs", "tomli ; python_version < \"3.11\""]
-dash = ["dash"]
-dev = ["anywidget", "dash", "ipykernel", "jupyterlab", "jupytext", "marimo", "matplotlib", "nbconvert", "platformdirs", "polars", "pyarrow", "pytest", "pytest-cov", "pytz", "requests", "shiny", "shinywidgets", "streamlit", "tomli ; python_version < \"3.11\"", "traitlets", "typeguard (>=4.4.1)", "watchfiles", "world-bank-data"]
-polars = ["polars", "pyarrow"]
-samples = ["pytz", "world-bank-data"]
-shiny = ["shiny", "shinywidgets"]
-streamlit = ["streamlit"]
-style = ["matplotlib"]
-test = ["anywidget", "dash", "ipykernel", "jupytext", "marimo", "matplotlib", "nbconvert", "platformdirs", "polars", "pyarrow", "pytest", "pytest-cov", "pytz", "requests", "shiny", "shinywidgets", "streamlit", "tomli ; python_version < \"3.11\"", "traitlets", "typeguard (>=4.4.1)", "world-bank-data"]
-widget = ["anywidget", "traitlets"]
-
-[[package]]
-name = "itsdangerous"
-version = "2.2.0"
-description = "Safely pass data to untrusted environments and back."
-optional = false
-python-versions = ">=3.8"
-groups = ["test"]
-files = [
- {file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"},
- {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"},
-]
-
-[[package]]
-name = "jedi"
-version = "0.19.2"
-description = "An autocompletion tool for Python that can be used for text editors."
-optional = false
-python-versions = ">=3.6"
-groups = ["eval"]
-files = [
- {file = "jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9"},
- {file = "jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0"},
-]
-
-[package.dependencies]
-parso = ">=0.8.4,<0.9.0"
-
-[package.extras]
-docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"]
-qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
-testing = ["Django", "attrs", "colorama", "docopt", "pytest (<9.0.0)"]
-
-[[package]]
-name = "jinja2"
-version = "3.1.6"
-description = "A very fast and expressive template engine."
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
- {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
-]
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "jiter"
-version = "0.10.0"
-description = "Fast iterable JSON parser."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "jiter-0.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:cd2fb72b02478f06a900a5782de2ef47e0396b3e1f7d5aba30daeb1fce66f303"},
- {file = "jiter-0.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:32bb468e3af278f095d3fa5b90314728a6916d89ba3d0ffb726dd9bf7367285e"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8b3e0068c26ddedc7abc6fac37da2d0af16b921e288a5a613f4b86f050354f"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:286299b74cc49e25cd42eea19b72aa82c515d2f2ee12d11392c56d8701f52224"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ed5649ceeaeffc28d87fb012d25a4cd356dcd53eff5acff1f0466b831dda2a7"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2ab0051160cb758a70716448908ef14ad476c3774bd03ddce075f3c1f90a3d6"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03997d2f37f6b67d2f5c475da4412be584e1cec273c1cfc03d642c46db43f8cf"},
- {file = "jiter-0.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c404a99352d839fed80d6afd6c1d66071f3bacaaa5c4268983fc10f769112e90"},
- {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66e989410b6666d3ddb27a74c7e50d0829704ede652fd4c858e91f8d64b403d0"},
- {file = "jiter-0.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b532d3af9ef4f6374609a3bcb5e05a1951d3bf6190dc6b176fdb277c9bbf15ee"},
- {file = "jiter-0.10.0-cp310-cp310-win32.whl", hash = "sha256:da9be20b333970e28b72edc4dff63d4fec3398e05770fb3205f7fb460eb48dd4"},
- {file = "jiter-0.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:f59e533afed0c5b0ac3eba20d2548c4a550336d8282ee69eb07b37ea526ee4e5"},
- {file = "jiter-0.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3bebe0c558e19902c96e99217e0b8e8b17d570906e72ed8a87170bc290b1e978"},
- {file = "jiter-0.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:558cc7e44fd8e507a236bee6a02fa17199ba752874400a0ca6cd6e2196cdb7dc"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d613e4b379a07d7c8453c5712ce7014e86c6ac93d990a0b8e7377e18505e98d"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f62cf8ba0618eda841b9bf61797f21c5ebd15a7a1e19daab76e4e4b498d515b2"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:919d139cdfa8ae8945112398511cb7fca58a77382617d279556b344867a37e61"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13ddbc6ae311175a3b03bd8994881bc4635c923754932918e18da841632349db"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c440ea003ad10927a30521a9062ce10b5479592e8a70da27f21eeb457b4a9c5"},
- {file = "jiter-0.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dc347c87944983481e138dea467c0551080c86b9d21de6ea9306efb12ca8f606"},
- {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:13252b58c1f4d8c5b63ab103c03d909e8e1e7842d302473f482915d95fefd605"},
- {file = "jiter-0.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7d1bbf3c465de4a24ab12fb7766a0003f6f9bce48b8b6a886158c4d569452dc5"},
- {file = "jiter-0.10.0-cp311-cp311-win32.whl", hash = "sha256:db16e4848b7e826edca4ccdd5b145939758dadf0dc06e7007ad0e9cfb5928ae7"},
- {file = "jiter-0.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:9c9c1d5f10e18909e993f9641f12fe1c77b3e9b533ee94ffa970acc14ded3812"},
- {file = "jiter-0.10.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1e274728e4a5345a6dde2d343c8da018b9d4bd4350f5a472fa91f66fda44911b"},
- {file = "jiter-0.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7202ae396446c988cb2a5feb33a543ab2165b786ac97f53b59aafb803fef0744"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23ba7722d6748b6920ed02a8f1726fb4b33e0fd2f3f621816a8b486c66410ab2"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:371eab43c0a288537d30e1f0b193bc4eca90439fc08a022dd83e5e07500ed026"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c675736059020365cebc845a820214765162728b51ab1e03a1b7b3abb70f74c"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0c5867d40ab716e4684858e4887489685968a47e3ba222e44cde6e4a2154f959"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395bb9a26111b60141757d874d27fdea01b17e8fac958b91c20128ba8f4acc8a"},
- {file = "jiter-0.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6842184aed5cdb07e0c7e20e5bdcfafe33515ee1741a6835353bb45fe5d1bd95"},
- {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:62755d1bcea9876770d4df713d82606c8c1a3dca88ff39046b85a048566d56ea"},
- {file = "jiter-0.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:533efbce2cacec78d5ba73a41756beff8431dfa1694b6346ce7af3a12c42202b"},
- {file = "jiter-0.10.0-cp312-cp312-win32.whl", hash = "sha256:8be921f0cadd245e981b964dfbcd6fd4bc4e254cdc069490416dd7a2632ecc01"},
- {file = "jiter-0.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:a7c7d785ae9dda68c2678532a5a1581347e9c15362ae9f6e68f3fdbfb64f2e49"},
- {file = "jiter-0.10.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e0588107ec8e11b6f5ef0e0d656fb2803ac6cf94a96b2b9fc675c0e3ab5e8644"},
- {file = "jiter-0.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cafc4628b616dc32530c20ee53d71589816cf385dd9449633e910d596b1f5c8a"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:520ef6d981172693786a49ff5b09eda72a42e539f14788124a07530f785c3ad6"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:554dedfd05937f8fc45d17ebdf298fe7e0c77458232bcb73d9fbbf4c6455f5b3"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc299da7789deacf95f64052d97f75c16d4fc8c4c214a22bf8d859a4288a1c2"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5161e201172de298a8a1baad95eb85db4fb90e902353b1f6a41d64ea64644e25"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2227db6ba93cb3e2bf67c87e594adde0609f146344e8207e8730364db27041"},
- {file = "jiter-0.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15acb267ea5e2c64515574b06a8bf393fbfee6a50eb1673614aa45f4613c0cca"},
- {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:901b92f2e2947dc6dfcb52fd624453862e16665ea909a08398dde19c0731b7f4"},
- {file = "jiter-0.10.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d0cb9a125d5a3ec971a094a845eadde2db0de85b33c9f13eb94a0c63d463879e"},
- {file = "jiter-0.10.0-cp313-cp313-win32.whl", hash = "sha256:48a403277ad1ee208fb930bdf91745e4d2d6e47253eedc96e2559d1e6527006d"},
- {file = "jiter-0.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:75f9eb72ecb640619c29bf714e78c9c46c9c4eaafd644bf78577ede459f330d4"},
- {file = "jiter-0.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:28ed2a4c05a1f32ef0e1d24c2611330219fed727dae01789f4a335617634b1ca"},
- {file = "jiter-0.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a4c418b1ec86a195f1ca69da8b23e8926c752b685af665ce30777233dfe070"},
- {file = "jiter-0.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:d7bfed2fe1fe0e4dda6ef682cee888ba444b21e7a6553e03252e4feb6cf0adca"},
- {file = "jiter-0.10.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:5e9251a5e83fab8d87799d3e1a46cb4b7f2919b895c6f4483629ed2446f66522"},
- {file = "jiter-0.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:023aa0204126fe5b87ccbcd75c8a0d0261b9abdbbf46d55e7ae9f8e22424eeb8"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c189c4f1779c05f75fc17c0c1267594ed918996a231593a21a5ca5438445216"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:15720084d90d1098ca0229352607cd68256c76991f6b374af96f36920eae13c4"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4f2fb68e5f1cfee30e2b2a09549a00683e0fde4c6a2ab88c94072fc33cb7426"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce541693355fc6da424c08b7edf39a2895f58d6ea17d92cc2b168d20907dee12"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31c50c40272e189d50006ad5c73883caabb73d4e9748a688b216e85a9a9ca3b9"},
- {file = "jiter-0.10.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fa3402a2ff9815960e0372a47b75c76979d74402448509ccd49a275fa983ef8a"},
- {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:1956f934dca32d7bb647ea21d06d93ca40868b505c228556d3373cbd255ce853"},
- {file = "jiter-0.10.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:fcedb049bdfc555e261d6f65a6abe1d5ad68825b7202ccb9692636c70fcced86"},
- {file = "jiter-0.10.0-cp314-cp314-win32.whl", hash = "sha256:ac509f7eccca54b2a29daeb516fb95b6f0bd0d0d8084efaf8ed5dfc7b9f0b357"},
- {file = "jiter-0.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5ed975b83a2b8639356151cef5c0d597c68376fc4922b45d0eb384ac058cfa00"},
- {file = "jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5"},
- {file = "jiter-0.10.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bd6292a43c0fc09ce7c154ec0fa646a536b877d1e8f2f96c19707f65355b5a4d"},
- {file = "jiter-0.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:39de429dcaeb6808d75ffe9effefe96a4903c6a4b376b2f6d08d77c1aaee2f18"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52ce124f13a7a616fad3bb723f2bfb537d78239d1f7f219566dc52b6f2a9e48d"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:166f3606f11920f9a1746b2eea84fa2c0a5d50fd313c38bdea4edc072000b0af"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28dcecbb4ba402916034fc14eba7709f250c4d24b0c43fc94d187ee0580af181"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86c5aa6910f9bebcc7bc4f8bc461aff68504388b43bfe5e5c0bd21efa33b52f4"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ceeb52d242b315d7f1f74b441b6a167f78cea801ad7c11c36da77ff2d42e8a28"},
- {file = "jiter-0.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ff76d8887c8c8ee1e772274fcf8cc1071c2c58590d13e33bd12d02dc9a560397"},
- {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a9be4d0fa2b79f7222a88aa488bd89e2ae0a0a5b189462a12def6ece2faa45f1"},
- {file = "jiter-0.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ab7fd8738094139b6c1ab1822d6f2000ebe41515c537235fd45dabe13ec9324"},
- {file = "jiter-0.10.0-cp39-cp39-win32.whl", hash = "sha256:5f51e048540dd27f204ff4a87f5d79294ea0aa3aa552aca34934588cf27023cf"},
- {file = "jiter-0.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b28302349dc65703a9e4ead16f163b1c339efffbe1049c30a44b001a2a4fff9"},
- {file = "jiter-0.10.0.tar.gz", hash = "sha256:07a7142c38aacc85194391108dc91b5b57093c978a9932bd86a36862759d9500"},
-]
-
-[[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 = "joblib"
-version = "1.5.2"
-description = "Lightweight pipelining with Python functions"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241"},
- {file = "joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55"},
-]
-
-[[package]]
-name = "json-repair"
-version = "0.53.0"
-description = "A package to repair broken json strings"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "json_repair-0.53.0-py3-none-any.whl", hash = "sha256:17f7439e41ae39964e1d678b1def38cb8ec43d607340564acf3e62d8ce47a727"},
- {file = "json_repair-0.53.0.tar.gz", hash = "sha256:97fcbf1eea0bbcf6d5cc94befc573623ab4bbba6abdc394cfd3b933a2571266d"},
-]
-
-[[package]]
-name = "jsonschema"
-version = "4.23.0"
-description = "An implementation of JSON Schema validation for Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566"},
- {file = "jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4"},
-]
-
-[package.dependencies]
-attrs = ">=22.2.0"
-jsonschema-specifications = ">=2023.3.6"
-referencing = ">=0.28.4"
-rpds-py = ">=0.7.1"
-
-[package.extras]
-format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
-format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"]
-
-[[package]]
-name = "jsonschema-specifications"
-version = "2025.9.1"
-description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe"},
- {file = "jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d"},
-]
-
-[package.dependencies]
-referencing = ">=0.31.0"
-
-[[package]]
-name = "jupyter-client"
-version = "8.6.3"
-description = "Jupyter protocol implementation and client libraries"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f"},
- {file = "jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419"},
-]
-
-[package.dependencies]
-jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
-python-dateutil = ">=2.8.2"
-pyzmq = ">=23.0"
-tornado = ">=6.2"
-traitlets = ">=5.3"
-
-[package.extras]
-docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
-test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko ; sys_platform == \"win32\"", "pre-commit", "pytest (<8.2.0)", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"]
-
-[[package]]
-name = "jupyter-core"
-version = "5.9.1"
-description = "Jupyter core package. A base package on which Jupyter projects rely."
-optional = false
-python-versions = ">=3.10"
-groups = ["eval"]
-files = [
- {file = "jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407"},
- {file = "jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508"},
-]
-
-[package.dependencies]
-platformdirs = ">=2.5"
-traitlets = ">=5.3"
-
-[package.extras]
-docs = ["intersphinx-registry", "myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-spelling", "traitlets"]
-test = ["ipykernel", "pre-commit", "pytest (<9)", "pytest-cov", "pytest-timeout"]
-
-[[package]]
-name = "kiwisolver"
-version = "1.4.9"
-description = "A fast implementation of the Cassowary constraint solver"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b"},
- {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f"},
- {file = "kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf"},
- {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9"},
- {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415"},
- {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b"},
- {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154"},
- {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48"},
- {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220"},
- {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586"},
- {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634"},
- {file = "kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611"},
- {file = "kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536"},
- {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16"},
- {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089"},
- {file = "kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543"},
- {file = "kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61"},
- {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1"},
- {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872"},
- {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26"},
- {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028"},
- {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771"},
- {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a"},
- {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464"},
- {file = "kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2"},
- {file = "kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7"},
- {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999"},
- {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2"},
- {file = "kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14"},
- {file = "kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04"},
- {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752"},
- {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77"},
- {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198"},
- {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d"},
- {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab"},
- {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2"},
- {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145"},
- {file = "kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54"},
- {file = "kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60"},
- {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8"},
- {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2"},
- {file = "kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f"},
- {file = "kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098"},
- {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed"},
- {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525"},
- {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78"},
- {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b"},
- {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799"},
- {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3"},
- {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c"},
- {file = "kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d"},
- {file = "kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07"},
- {file = "kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c"},
- {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386"},
- {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552"},
- {file = "kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3"},
- {file = "kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58"},
- {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4"},
- {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df"},
- {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6"},
- {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5"},
- {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf"},
- {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5"},
- {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce"},
- {file = "kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7"},
- {file = "kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891"},
- {file = "kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32"},
- {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527"},
- {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771"},
- {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e"},
- {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9"},
- {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb"},
- {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5"},
- {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa"},
- {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2"},
- {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f"},
- {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1"},
- {file = "kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d"},
-]
-
-[[package]]
-name = "langfuse"
-version = "2.60.10"
-description = "A client library for accessing langfuse"
-optional = false
-python-versions = "<4.0,>=3.9"
-groups = ["main"]
-files = [
- {file = "langfuse-2.60.10-py3-none-any.whl", hash = "sha256:815c6369194aa5b2a24f88eb9952f7c3fc863272c41e90642a71f3bc76f4a11f"},
- {file = "langfuse-2.60.10.tar.gz", hash = "sha256:a26d0d927a28ee01b2d12bb5b862590b643cc4e60a28de6e2b0c2cfff5dbfc6a"},
-]
-
-[package.dependencies]
-anyio = ">=4.4.0,<5.0.0"
-backoff = ">=1.10.0"
-httpx = ">=0.15.4,<1.0"
-idna = ">=3.7,<4.0"
-packaging = ">=23.2,<25.0"
-pydantic = ">=1.10.7,<3.0"
-requests = ">=2,<3"
-wrapt = ">=1.14,<2.0"
-
-[package.extras]
-langchain = ["langchain (>=0.0.309)"]
-llama-index = ["llama-index (>=0.10.12,<2.0.0)"]
-openai = ["openai (>=0.27.8)"]
-
-[[package]]
-name = "lazy-imports"
-version = "1.1.0"
-description = "Tool to support lazy imports"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "lazy_imports-1.1.0-py3-none-any.whl", hash = "sha256:49fb1034ffe325fbec6e1f0e1e5b47eaaf43989b17be6c090added97c2b3ec24"},
- {file = "lazy_imports-1.1.0.tar.gz", hash = "sha256:e6ea5a1e4f09a861357e670b7aa61efcbce6fe29361785dd253df66f8ddbc36b"},
-]
-
-[package.extras]
-all = ["black", "flake8", "isort", "mdformat", "mypy", "packaging", "pydocstyle", "pylint", "pylintfileheader", "pytest"]
-checking = ["black", "flake8", "isort", "mdformat", "mypy", "pydocstyle", "pylint", "pylintfileheader"]
-testing = ["packaging", "pytest"]
-
-[[package]]
-name = "litellm"
-version = "1.83.14"
-description = "Library to easily interface with LLM API providers"
-optional = false
-python-versions = "<3.14,>=3.10"
-groups = ["main", "dev"]
-files = [
- {file = "litellm-1.83.14-py3-none-any.whl", hash = "sha256:92b11ba2a32cf80707ddf388d18526696c7999a21b418c5e3b6eda1243d2cfdb"},
- {file = "litellm-1.83.14.tar.gz", hash = "sha256:24aef9b47cdc424c833e32f3727f411741c690832cd1fe4405e0077144fe09c9"},
-]
-
-[package.dependencies]
-aiohttp = "3.13.4"
-click = "8.1.8"
-fastuuid = "0.14.0"
-httpx = "0.28.1"
-importlib-metadata = "8.5.0"
-jinja2 = "3.1.6"
-jsonschema = "4.23.0"
-openai = "2.24.0"
-pydantic = "2.12.5"
-python-dotenv = "1.2.2"
-tiktoken = "0.12.0"
-tokenizers = "0.22.2"
-
-[package.extras]
-caching = ["diskcache (==5.6.3)"]
-extra-proxy = ["a2a-sdk (==0.3.24)", "azure-identity (==1.25.2)", "azure-keyvault-secrets (==4.10.0)", "google-cloud-iam (==2.19.1)", "google-cloud-kms (==2.24.2)", "prisma (==0.11.0)", "redisvl (==0.4.1) ; python_full_version < \"3.14.0\"", "resend (==2.23.0)"]
-google = ["google-cloud-aiplatform (==1.133.0)"]
-grpc = ["grpcio (==1.78.0)"]
-mlflow = ["mlflow (==3.11.1)"]
-proxy = ["apscheduler (==3.11.2)", "azure-identity (==1.25.2)", "azure-storage-blob (==12.28.0)", "backoff (==2.2.1)", "boto3 (==1.42.59)", "cryptography (==46.0.7)", "fastapi (==0.124.4)", "fastapi-sso (==0.19.0)", "gunicorn (==23.0.0)", "litellm-enterprise (==0.1.39)", "litellm-proxy-extras (==0.4.69)", "mcp (==1.26.0)", "orjson (==3.11.6)", "polars (==1.38.1)", "pyjwt (==2.12.0)", "pynacl (==1.6.2)", "pyroscope-io (==0.8.16) ; sys_platform != \"win32\"", "python-multipart (==0.0.26)", "pyyaml (==6.0.3)", "restrictedpython (==8.1)", "rich (==13.9.4)", "rq (==2.7.0)", "soundfile (==0.12.1)", "uvicorn (==0.33.0)", "uvloop (==0.21.0) ; sys_platform != \"win32\"", "websockets (==15.0.1)"]
-proxy-runtime = ["anthropic[vertex] (==0.84.0)", "azure-ai-contentsafety (==1.0.0)", "azure-storage-file-datalake (==12.20.0)", "ddtrace (==2.19.0)", "detect-secrets (==1.5.0)", "google-cloud-aiplatform (==1.133.0)", "google-genai (==1.37.0)", "grpcio (==1.78.0)", "langfuse (==2.59.7)", "llm-sandbox (==0.3.39)", "mangum (==0.17.0)", "opentelemetry-api (==1.28.0)", "opentelemetry-exporter-otlp (==1.28.0)", "opentelemetry-sdk (==1.28.0)", "prometheus-client (==0.20.0)", "pypdf (==6.10.2) ; python_full_version < \"3.14.0\"", "sentry-sdk (==2.21.0)"]
-semantic-router = ["aurelio-sdk (==0.0.19) ; python_full_version < \"3.14.0\"", "semantic-router (==0.1.12) ; python_full_version < \"3.14.0\""]
-utils = ["numpydoc (==1.8.0)"]
-
-[[package]]
-name = "locust"
-version = "2.41.6"
-description = "Developer-friendly load testing framework"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "locust-2.41.6-py3-none-any.whl", hash = "sha256:6679bf9e2d92e3c6500551f29dfa58a84d6f767d398cedefbc8a4765659a2126"},
- {file = "locust-2.41.6.tar.gz", hash = "sha256:1fd76545f41639ba8c1ee57b5cafdf8bd426a264a0656fd927a99040bb86150b"},
-]
-
-[package.dependencies]
-configargparse = ">=1.7.1"
-flask = ">=2.0.0"
-flask-cors = ">=3.0.10"
-flask-login = ">=0.6.3"
-gevent = ">=24.10.1,<25.8.1"
-geventhttpclient = ">=2.3.1"
-locust-cloud = ">=1.27.2"
-msgpack = ">=1.0.0"
-psutil = ">=5.9.1"
-pytest = ">=8.3.3,<9.0.0"
-python-engineio = ">=4.12.2"
-python-socketio = {version = ">=5.13.0", extras = ["client"]}
-pywin32 = {version = "*", markers = "sys_platform == \"win32\""}
-pyzmq = ">=25.0.0"
-requests = ">=2.32.2"
-setuptools = ">=70.0.0"
-werkzeug = ">=2.0.0"
-
-[package.extras]
-milvus = ["pymilvus (>=2.5.0)"]
-mqtt = ["paho-mqtt (>=2.1.0)"]
-
-[[package]]
-name = "locust-cloud"
-version = "1.28.1"
-description = "Locust Cloud"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "locust_cloud-1.28.1-py3-none-any.whl", hash = "sha256:fadfd423dd83057b96c4332e8fdb94ccacaecbb6b8ae837212c42276b8b5c22e"},
- {file = "locust_cloud-1.28.1.tar.gz", hash = "sha256:c010a80dbd26fbd791a9c1202c63c59ddb96e9f3cc4ff5af48a9ee858057a56c"},
-]
-
-[package.dependencies]
-configargparse = ">=1.7.1"
-gevent = ">=24.10.1,<26.0.0"
-platformdirs = ">=4.3.6,<5.0.0"
-python-engineio = ">=4.12.2"
-python-socketio = {version = ">=5.14.1,<6.0.0", extras = ["client"]}
-
-[[package]]
-name = "magicattr"
-version = "0.1.6"
-description = "A getattr and setattr that works on nested objects, lists, dicts, and any combination thereof without resorting to eval"
-optional = false
-python-versions = "*"
-groups = ["dev"]
-files = [
- {file = "magicattr-0.1.6-py2.py3-none-any.whl", hash = "sha256:d96b18ee45b5ee83b09c17e15d3459a64de62d538808c2f71182777dd9dbbbdf"},
-]
-
-[[package]]
-name = "mako"
-version = "1.3.10"
-description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59"},
- {file = "mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28"},
-]
-
-[package.dependencies]
-MarkupSafe = ">=0.9.2"
-
-[package.extras]
-babel = ["Babel"]
-lingua = ["lingua"]
-testing = ["pytest"]
-
-[[package]]
-name = "markdown-it-py"
-version = "4.0.0"
-description = "Python port of markdown-it. Markdown parsing, done right!"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev"]
-files = [
- {file = "markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147"},
- {file = "markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"},
-]
-
-[package.dependencies]
-mdurl = ">=0.1,<1.0"
-
-[package.extras]
-benchmarking = ["psutil", "pytest", "pytest-benchmark"]
-compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"]
-linkify = ["linkify-it-py (>=1,<3)"]
-plugins = ["mdit-py-plugins (>=0.5.0)"]
-profiling = ["gprof2dot"]
-rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"]
-testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "requests"]
-
-[[package]]
-name = "markupsafe"
-version = "3.0.3"
-description = "Safely add untrusted strings to HTML/XML markup."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "markupsafe-3.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559"},
- {file = "markupsafe-3.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419"},
- {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695"},
- {file = "markupsafe-3.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591"},
- {file = "markupsafe-3.0.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c"},
- {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f"},
- {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6"},
- {file = "markupsafe-3.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1"},
- {file = "markupsafe-3.0.3-cp310-cp310-win32.whl", hash = "sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa"},
- {file = "markupsafe-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8"},
- {file = "markupsafe-3.0.3-cp310-cp310-win_arm64.whl", hash = "sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1"},
- {file = "markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad"},
- {file = "markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a"},
- {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50"},
- {file = "markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf"},
- {file = "markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f"},
- {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a"},
- {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115"},
- {file = "markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a"},
- {file = "markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19"},
- {file = "markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01"},
- {file = "markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c"},
- {file = "markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e"},
- {file = "markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce"},
- {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d"},
- {file = "markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d"},
- {file = "markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a"},
- {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b"},
- {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f"},
- {file = "markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b"},
- {file = "markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d"},
- {file = "markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c"},
- {file = "markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f"},
- {file = "markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795"},
- {file = "markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219"},
- {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6"},
- {file = "markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676"},
- {file = "markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9"},
- {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1"},
- {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc"},
- {file = "markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12"},
- {file = "markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed"},
- {file = "markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5"},
- {file = "markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485"},
- {file = "markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73"},
- {file = "markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37"},
- {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19"},
- {file = "markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025"},
- {file = "markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6"},
- {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f"},
- {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb"},
- {file = "markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009"},
- {file = "markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354"},
- {file = "markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218"},
- {file = "markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287"},
- {file = "markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe"},
- {file = "markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026"},
- {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737"},
- {file = "markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97"},
- {file = "markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d"},
- {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda"},
- {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf"},
- {file = "markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe"},
- {file = "markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9"},
- {file = "markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581"},
- {file = "markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4"},
- {file = "markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab"},
- {file = "markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175"},
- {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634"},
- {file = "markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50"},
- {file = "markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e"},
- {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5"},
- {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523"},
- {file = "markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc"},
- {file = "markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d"},
- {file = "markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9"},
- {file = "markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa"},
- {file = "markupsafe-3.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26"},
- {file = "markupsafe-3.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc"},
- {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c"},
- {file = "markupsafe-3.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42"},
- {file = "markupsafe-3.0.3-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b"},
- {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758"},
- {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2"},
- {file = "markupsafe-3.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d"},
- {file = "markupsafe-3.0.3-cp39-cp39-win32.whl", hash = "sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7"},
- {file = "markupsafe-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e"},
- {file = "markupsafe-3.0.3-cp39-cp39-win_arm64.whl", hash = "sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8"},
- {file = "markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698"},
-]
-
-[[package]]
-name = "marshmallow"
-version = "3.26.2"
-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.2-py3-none-any.whl", hash = "sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73"},
- {file = "marshmallow-3.26.2.tar.gz", hash = "sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57"},
-]
-
-[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 = "matplotlib"
-version = "3.10.7"
-description = "Python plotting package"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "matplotlib-3.10.7-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7ac81eee3b7c266dd92cee1cd658407b16c57eed08c7421fa354ed68234de380"},
- {file = "matplotlib-3.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:667ecd5d8d37813a845053d8f5bf110b534c3c9f30e69ebd25d4701385935a6d"},
- {file = "matplotlib-3.10.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc1c51b846aca49a5a8b44fbba6a92d583a35c64590ad9e1e950dc88940a4297"},
- {file = "matplotlib-3.10.7-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a11c2e9e72e7de09b7b72e62f3df23317c888299c875e2b778abf1eda8c0a42"},
- {file = "matplotlib-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f19410b486fdd139885ace124e57f938c1e6a3210ea13dd29cab58f5d4bc12c7"},
- {file = "matplotlib-3.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:b498e9e4022f93de2d5a37615200ca01297ceebbb56fe4c833f46862a490f9e3"},
- {file = "matplotlib-3.10.7-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:53b492410a6cd66c7a471de6c924f6ede976e963c0f3097a3b7abfadddc67d0a"},
- {file = "matplotlib-3.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d9749313deb729f08207718d29c86246beb2ea3fdba753595b55901dee5d2fd6"},
- {file = "matplotlib-3.10.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2222c7ba2cbde7fe63032769f6eb7e83ab3227f47d997a8453377709b7fe3a5a"},
- {file = "matplotlib-3.10.7-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e91f61a064c92c307c5a9dc8c05dc9f8a68f0a3be199d9a002a0622e13f874a1"},
- {file = "matplotlib-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6f1851eab59ca082c95df5a500106bad73672645625e04538b3ad0f69471ffcc"},
- {file = "matplotlib-3.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:6516ce375109c60ceec579e699524e9d504cd7578506f01150f7a6bc174a775e"},
- {file = "matplotlib-3.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:b172db79759f5f9bc13ef1c3ef8b9ee7b37b0247f987fbbbdaa15e4f87fd46a9"},
- {file = "matplotlib-3.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7a0edb7209e21840e8361e91ea84ea676658aa93edd5f8762793dec77a4a6748"},
- {file = "matplotlib-3.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c380371d3c23e0eadf8ebff114445b9f970aff2010198d498d4ab4c3b41eea4f"},
- {file = "matplotlib-3.10.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5f256d49fea31f40f166a5e3131235a5d2f4b7f44520b1cf0baf1ce568ccff0"},
- {file = "matplotlib-3.10.7-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11ae579ac83cdf3fb72573bb89f70e0534de05266728740d478f0f818983c695"},
- {file = "matplotlib-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4c14b6acd16cddc3569a2d515cfdd81c7a68ac5639b76548cfc1a9e48b20eb65"},
- {file = "matplotlib-3.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:0d8c32b7ea6fb80b1aeff5a2ceb3fb9778e2759e899d9beff75584714afcc5ee"},
- {file = "matplotlib-3.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:5f3f6d315dcc176ba7ca6e74c7768fb7e4cf566c49cb143f6bc257b62e634ed8"},
- {file = "matplotlib-3.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1d9d3713a237970569156cfb4de7533b7c4eacdd61789726f444f96a0d28f57f"},
- {file = "matplotlib-3.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37a1fea41153dd6ee061d21ab69c9cf2cf543160b1b85d89cd3d2e2a7902ca4c"},
- {file = "matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1"},
- {file = "matplotlib-3.10.7-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22df30ffaa89f6643206cf13877191c63a50e8f800b038bc39bee9d2d4957632"},
- {file = "matplotlib-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b69676845a0a66f9da30e87f48be36734d6748024b525ec4710be40194282c84"},
- {file = "matplotlib-3.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:744991e0cc863dd669c8dc9136ca4e6e0082be2070b9d793cbd64bec872a6815"},
- {file = "matplotlib-3.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:fba2974df0bf8ce3c995fa84b79cde38326e0f7b5409e7a3a481c1141340bcf7"},
- {file = "matplotlib-3.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:932c55d1fa7af4423422cb6a492a31cbcbdbe68fd1a9a3f545aa5e7a143b5355"},
- {file = "matplotlib-3.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e38c2d581d62ee729a6e144c47a71b3f42fb4187508dbbf4fe71d5612c3433b"},
- {file = "matplotlib-3.10.7-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:786656bb13c237bbcebcd402f65f44dd61ead60ee3deb045af429d889c8dbc67"},
- {file = "matplotlib-3.10.7-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09d7945a70ea43bf9248f4b6582734c2fe726723204a76eca233f24cffc7ef67"},
- {file = "matplotlib-3.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0b181e9fa8daf1d9f2d4c547527b167cb8838fc587deabca7b5c01f97199e84"},
- {file = "matplotlib-3.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:31963603041634ce1a96053047b40961f7a29eb8f9a62e80cc2c0427aa1d22a2"},
- {file = "matplotlib-3.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:aebed7b50aa6ac698c90f60f854b47e48cd2252b30510e7a1feddaf5a3f72cbf"},
- {file = "matplotlib-3.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d883460c43e8c6b173fef244a2341f7f7c0e9725c7fe68306e8e44ed9c8fb100"},
- {file = "matplotlib-3.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:07124afcf7a6504eafcb8ce94091c5898bbdd351519a1beb5c45f7a38c67e77f"},
- {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c17398b709a6cce3d9fdb1595c33e356d91c098cd9486cb2cc21ea2ea418e715"},
- {file = "matplotlib-3.10.7-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7146d64f561498764561e9cd0ed64fcf582e570fc519e6f521e2d0cfd43365e1"},
- {file = "matplotlib-3.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:90ad854c0a435da3104c01e2c6f0028d7e719b690998a2333d7218db80950722"},
- {file = "matplotlib-3.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:4645fc5d9d20ffa3a39361fcdbcec731382763b623b72627806bf251b6388866"},
- {file = "matplotlib-3.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:9257be2f2a03415f9105c486d304a321168e61ad450f6153d77c69504ad764bb"},
- {file = "matplotlib-3.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1e4bbad66c177a8fdfa53972e5ef8be72a5f27e6a607cec0d8579abd0f3102b1"},
- {file = "matplotlib-3.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8eb7194b084b12feb19142262165832fc6ee879b945491d1c3d4660748020c4"},
- {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d41379b05528091f00e1728004f9a8d7191260f3862178b88e8fd770206318"},
- {file = "matplotlib-3.10.7-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a74f79fafb2e177f240579bc83f0b60f82cc47d2f1d260f422a0627207008ca"},
- {file = "matplotlib-3.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:702590829c30aada1e8cef0568ddbffa77ca747b4d6e36c6d173f66e301f89cc"},
- {file = "matplotlib-3.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:f79d5de970fc90cd5591f60053aecfce1fcd736e0303d9f0bf86be649fa68fb8"},
- {file = "matplotlib-3.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:cb783436e47fcf82064baca52ce748af71725d0352e1d31564cbe9c95df92b9c"},
- {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5c09cf8f2793f81368f49f118b6f9f937456362bee282eac575cca7f84cda537"},
- {file = "matplotlib-3.10.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:de66744b2bb88d5cd27e80dfc2ec9f0517d0a46d204ff98fe9e5f2864eb67657"},
- {file = "matplotlib-3.10.7-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53cc80662dd197ece414dd5b66e07370201515a3eaf52e7c518c68c16814773b"},
- {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:15112bcbaef211bd663fa935ec33313b948e214454d949b723998a43357b17b0"},
- {file = "matplotlib-3.10.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d2a959c640cdeecdd2ec3136e8ea0441da59bcaf58d67e9c590740addba2cb68"},
- {file = "matplotlib-3.10.7-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3886e47f64611046bc1db523a09dd0a0a6bed6081e6f90e13806dd1d1d1b5e91"},
- {file = "matplotlib-3.10.7.tar.gz", hash = "sha256:a06ba7e2a2ef9131c79c49e63dad355d2d878413a0376c1727c8b9335ff731c7"},
-]
-
-[package.dependencies]
-contourpy = ">=1.0.1"
-cycler = ">=0.10"
-fonttools = ">=4.22.0"
-kiwisolver = ">=1.3.1"
-numpy = ">=1.23"
-packaging = ">=20.0"
-pillow = ">=8"
-pyparsing = ">=3"
-python-dateutil = ">=2.7"
-
-[package.extras]
-dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7)"]
-
-[[package]]
-name = "matplotlib-inline"
-version = "0.2.1"
-description = "Inline Matplotlib backend for Jupyter"
-optional = false
-python-versions = ">=3.9"
-groups = ["eval"]
-files = [
- {file = "matplotlib_inline-0.2.1-py3-none-any.whl", hash = "sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76"},
- {file = "matplotlib_inline-0.2.1.tar.gz", hash = "sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe"},
-]
-
-[package.dependencies]
-traitlets = "*"
-
-[package.extras]
-test = ["flake8", "nbdime", "nbval", "notebook", "pytest"]
-
-[[package]]
-name = "mdurl"
-version = "0.1.2"
-description = "Markdown URL utilities"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev"]
-files = [
- {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
- {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
-]
-
-[[package]]
-name = "more-itertools"
-version = "10.8.0"
-description = "More routines for operating on iterables, beyond itertools"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "more_itertools-10.8.0-py3-none-any.whl", hash = "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b"},
- {file = "more_itertools-10.8.0.tar.gz", hash = "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd"},
-]
-
-[[package]]
-name = "msgpack"
-version = "1.1.2"
-description = "MessagePack serializer"
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "msgpack-1.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2"},
- {file = "msgpack-1.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87"},
- {file = "msgpack-1.1.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251"},
- {file = "msgpack-1.1.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a"},
- {file = "msgpack-1.1.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f"},
- {file = "msgpack-1.1.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f"},
- {file = "msgpack-1.1.2-cp310-cp310-win32.whl", hash = "sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9"},
- {file = "msgpack-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa"},
- {file = "msgpack-1.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c"},
- {file = "msgpack-1.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0"},
- {file = "msgpack-1.1.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296"},
- {file = "msgpack-1.1.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef"},
- {file = "msgpack-1.1.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c"},
- {file = "msgpack-1.1.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e"},
- {file = "msgpack-1.1.2-cp311-cp311-win32.whl", hash = "sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e"},
- {file = "msgpack-1.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68"},
- {file = "msgpack-1.1.2-cp311-cp311-win_arm64.whl", hash = "sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406"},
- {file = "msgpack-1.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa"},
- {file = "msgpack-1.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb"},
- {file = "msgpack-1.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f"},
- {file = "msgpack-1.1.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42"},
- {file = "msgpack-1.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9"},
- {file = "msgpack-1.1.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620"},
- {file = "msgpack-1.1.2-cp312-cp312-win32.whl", hash = "sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029"},
- {file = "msgpack-1.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b"},
- {file = "msgpack-1.1.2-cp312-cp312-win_arm64.whl", hash = "sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69"},
- {file = "msgpack-1.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf"},
- {file = "msgpack-1.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7"},
- {file = "msgpack-1.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999"},
- {file = "msgpack-1.1.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e"},
- {file = "msgpack-1.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162"},
- {file = "msgpack-1.1.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794"},
- {file = "msgpack-1.1.2-cp313-cp313-win32.whl", hash = "sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c"},
- {file = "msgpack-1.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9"},
- {file = "msgpack-1.1.2-cp313-cp313-win_arm64.whl", hash = "sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84"},
- {file = "msgpack-1.1.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00"},
- {file = "msgpack-1.1.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939"},
- {file = "msgpack-1.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e"},
- {file = "msgpack-1.1.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931"},
- {file = "msgpack-1.1.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014"},
- {file = "msgpack-1.1.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2"},
- {file = "msgpack-1.1.2-cp314-cp314-win32.whl", hash = "sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717"},
- {file = "msgpack-1.1.2-cp314-cp314-win_amd64.whl", hash = "sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b"},
- {file = "msgpack-1.1.2-cp314-cp314-win_arm64.whl", hash = "sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af"},
- {file = "msgpack-1.1.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a"},
- {file = "msgpack-1.1.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b"},
- {file = "msgpack-1.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245"},
- {file = "msgpack-1.1.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90"},
- {file = "msgpack-1.1.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20"},
- {file = "msgpack-1.1.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27"},
- {file = "msgpack-1.1.2-cp314-cp314t-win32.whl", hash = "sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b"},
- {file = "msgpack-1.1.2-cp314-cp314t-win_amd64.whl", hash = "sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff"},
- {file = "msgpack-1.1.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46"},
- {file = "msgpack-1.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ea5405c46e690122a76531ab97a079e184c0daf491e588592d6a23d3e32af99e"},
- {file = "msgpack-1.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9fba231af7a933400238cb357ecccf8ab5d51535ea95d94fc35b7806218ff844"},
- {file = "msgpack-1.1.2-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a8f6e7d30253714751aa0b0c84ae28948e852ee7fb0524082e6716769124bc23"},
- {file = "msgpack-1.1.2-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94fd7dc7d8cb0a54432f296f2246bc39474e017204ca6f4ff345941d4ed285a7"},
- {file = "msgpack-1.1.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:350ad5353a467d9e3b126d8d1b90fe05ad081e2e1cef5753f8c345217c37e7b8"},
- {file = "msgpack-1.1.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6bde749afe671dc44893f8d08e83bf475a1a14570d67c4bb5cec5573463c8833"},
- {file = "msgpack-1.1.2-cp39-cp39-win32.whl", hash = "sha256:ad09b984828d6b7bb52d1d1d0c9be68ad781fa004ca39216c8a1e63c0f34ba3c"},
- {file = "msgpack-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:67016ae8c8965124fdede9d3769528ad8284f14d635337ffa6a713a580f6c030"},
- {file = "msgpack-1.1.2.tar.gz", hash = "sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e"},
-]
-
-[[package]]
-name = "multidict"
-version = "6.7.0"
-description = "multidict implementation"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "multidict-6.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349"},
- {file = "multidict-6.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e"},
- {file = "multidict-6.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62"},
- {file = "multidict-6.7.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111"},
- {file = "multidict-6.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36"},
- {file = "multidict-6.7.0-cp310-cp310-win32.whl", hash = "sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85"},
- {file = "multidict-6.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7"},
- {file = "multidict-6.7.0-cp310-cp310-win_arm64.whl", hash = "sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0"},
- {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc"},
- {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721"},
- {file = "multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8"},
- {file = "multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b"},
- {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34"},
- {file = "multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff"},
- {file = "multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81"},
- {file = "multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912"},
- {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184"},
- {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45"},
- {file = "multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1"},
- {file = "multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a"},
- {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8"},
- {file = "multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4"},
- {file = "multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b"},
- {file = "multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec"},
- {file = "multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6"},
- {file = "multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159"},
- {file = "multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf"},
- {file = "multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd"},
- {file = "multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288"},
- {file = "multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17"},
- {file = "multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390"},
- {file = "multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e"},
- {file = "multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00"},
- {file = "multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb"},
- {file = "multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad"},
- {file = "multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762"},
- {file = "multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6"},
- {file = "multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d"},
- {file = "multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6"},
- {file = "multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792"},
- {file = "multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842"},
- {file = "multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b"},
- {file = "multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1"},
- {file = "multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f"},
- {file = "multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f"},
- {file = "multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885"},
- {file = "multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c"},
- {file = "multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000"},
- {file = "multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63"},
- {file = "multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718"},
- {file = "multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a"},
- {file = "multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9"},
- {file = "multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0"},
- {file = "multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13"},
- {file = "multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd"},
- {file = "multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827"},
- {file = "multidict-6.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c"},
- {file = "multidict-6.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40"},
- {file = "multidict-6.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e"},
- {file = "multidict-6.7.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e"},
- {file = "multidict-6.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4"},
- {file = "multidict-6.7.0-cp39-cp39-win32.whl", hash = "sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91"},
- {file = "multidict-6.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f"},
- {file = "multidict-6.7.0-cp39-cp39-win_arm64.whl", hash = "sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546"},
- {file = "multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3"},
- {file = "multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5"},
-]
-
-[[package]]
-name = "mypy-extensions"
-version = "1.1.0"
-description = "Type system extensions for programs checked with the mypy type checker."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"},
- {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"},
-]
-
-[[package]]
-name = "narwhals"
-version = "2.11.0"
-description = "Extremely lightweight compatibility layer between dataframe libraries"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "eval"]
-files = [
- {file = "narwhals-2.11.0-py3-none-any.whl", hash = "sha256:a9795e1e44aa94e5ba6406ef1c5ee4c172414ced4f1aea4a79e5894f0c7378d4"},
- {file = "narwhals-2.11.0.tar.gz", hash = "sha256:d23f3ea7efc6b4d0355444a72de6b8fa3011175585246c3400c894a7583964af"},
-]
-
-[package.extras]
-cudf = ["cudf (>=24.10.0)"]
-dask = ["dask[dataframe] (>=2024.8)"]
-duckdb = ["duckdb (>=1.1)"]
-ibis = ["ibis-framework (>=6.0.0)", "packaging", "pyarrow-hotfix", "rich"]
-modin = ["modin"]
-pandas = ["pandas (>=1.1.3)"]
-polars = ["polars (>=0.20.4)"]
-pyarrow = ["pyarrow (>=13.0.0)"]
-pyspark = ["pyspark (>=3.5.0)"]
-pyspark-connect = ["pyspark[connect] (>=3.5.0)"]
-sqlframe = ["sqlframe (>=3.22.0,!=3.39.3)"]
-
-[[package]]
-name = "nbformat"
-version = "5.10.4"
-description = "The Jupyter Notebook format"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b"},
- {file = "nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a"},
-]
-
-[package.dependencies]
-fastjsonschema = ">=2.15"
-jsonschema = ">=2.6"
-jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0"
-traitlets = ">=5.1"
-
-[package.extras]
-docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"]
-test = ["pep440", "pre-commit", "pytest", "testpath"]
-
-[[package]]
-name = "nest-asyncio"
-version = "1.6.0"
-description = "Patch asyncio to allow nested event loops"
-optional = false
-python-versions = ">=3.5"
-groups = ["dev", "eval"]
-files = [
- {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"},
- {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
-]
-
-[[package]]
-name = "networkx"
-version = "3.5"
-description = "Python package for creating and manipulating graphs and networks"
-optional = false
-python-versions = ">=3.11"
-groups = ["main"]
-files = [
- {file = "networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec"},
- {file = "networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037"},
-]
-
-[package.extras]
-default = ["matplotlib (>=3.8)", "numpy (>=1.25)", "pandas (>=2.0)", "scipy (>=1.11.2)"]
-developer = ["mypy (>=1.15)", "pre-commit (>=4.1)"]
-doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=10)", "pydata-sphinx-theme (>=0.16)", "sphinx (>=8.0)", "sphinx-gallery (>=0.18)", "texext (>=0.6.7)"]
-example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=2.0.0)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"]
-extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"]
-test = ["pytest (>=7.2)", "pytest-cov (>=4.0)", "pytest-xdist (>=3.0)"]
-test-extras = ["pytest-mpl", "pytest-randomly"]
-
-[[package]]
-name = "nltk"
-version = "3.9.3"
-description = "Natural Language Toolkit"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "nltk-3.9.3-py3-none-any.whl", hash = "sha256:60b3db6e9995b3dd976b1f0fa7dec22069b2677e759c28eb69b62ddd44870522"},
- {file = "nltk-3.9.3.tar.gz", hash = "sha256:cb5945d6424a98d694c2b9a0264519fab4363711065a46aa0ae7a2195b92e71f"},
-]
-
-[package.dependencies]
-click = "*"
-joblib = "*"
-regex = ">=2021.8.3"
-tqdm = "*"
-
-[package.extras]
-all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"]
-corenlp = ["requests"]
-machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"]
-plot = ["matplotlib"]
-tgrep = ["pyparsing"]
-twitter = ["twython"]
-
-[[package]]
-name = "nodeenv"
-version = "1.9.1"
-description = "Node.js virtual environment builder"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
-groups = ["dev"]
-files = [
- {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
- {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
-]
-
-[[package]]
-name = "numpy"
-version = "1.26.4"
-description = "Fundamental package for array computing in Python"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval"]
-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 = "ollama"
-version = "0.4.9"
-description = "The official Python client for Ollama."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "ollama-0.4.9-py3-none-any.whl", hash = "sha256:18c8c85358c54d7f73d6a66cda495b0e3ba99fdb88f824ae470d740fbb211a50"},
- {file = "ollama-0.4.9.tar.gz", hash = "sha256:5266d4d29b5089a01489872b8e8f980f018bccbdd1082b3903448af1d5615ce7"},
-]
-
-[package.dependencies]
-httpx = ">=0.27"
-pydantic = ">=2.9"
-
-[[package]]
-name = "ollama-haystack"
-version = "2.4.2"
-description = "An integration between the Ollama LLM framework and Haystack"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "ollama_haystack-2.4.2-py3-none-any.whl", hash = "sha256:5cf06f26de8461a65b9e141d14a51a3e2bc347265d479993a4d4a3fbb2d7e39e"},
- {file = "ollama_haystack-2.4.2.tar.gz", hash = "sha256:137c8529673b026b2b98bc93bf891871c9df47ceb8530412ae5f942a5992c955"},
-]
-
-[package.dependencies]
-haystack-ai = "*"
-ollama = ">=0.4.0"
-pydantic = "*"
-
-[[package]]
-name = "openai"
-version = "2.24.0"
-description = "The official Python library for the openai API"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "openai-2.24.0-py3-none-any.whl", hash = "sha256:fed30480d7d6c884303287bde864980a4b137b60553ffbcf9ab4a233b7a73d94"},
- {file = "openai-2.24.0.tar.gz", hash = "sha256:1e5769f540dbd01cb33bc4716a23e67b9d695161a734aff9c5f925e2bf99a673"},
-]
-
-[package.dependencies]
-anyio = ">=3.5.0,<5"
-distro = ">=1.7.0,<2"
-httpx = ">=0.23.0,<1"
-jiter = ">=0.10.0,<1"
-pydantic = ">=1.9.0,<3"
-sniffio = "*"
-tqdm = ">4"
-typing-extensions = ">=4.11,<5"
-
-[package.extras]
-aiohttp = ["aiohttp", "httpx-aiohttp (>=0.1.9)"]
-datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
-realtime = ["websockets (>=13,<16)"]
-voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"]
-
-[[package]]
-name = "opentelemetry-api"
-version = "1.41.1"
-description = "OpenTelemetry Python API"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "opentelemetry_api-1.41.1-py3-none-any.whl", hash = "sha256:a22df900e75c76dc08440710e51f52f1aa6b451b429298896023e60db5b3139f"},
- {file = "opentelemetry_api-1.41.1.tar.gz", hash = "sha256:0ad1814d73b875f84494387dae86ce0b12c68556331ce6ce8fe789197c949621"},
-]
-
-[package.dependencies]
-importlib-metadata = ">=6.0,<8.8.0"
-typing-extensions = ">=4.5.0"
-
-[[package]]
-name = "opentelemetry-sdk"
-version = "1.41.1"
-description = "OpenTelemetry Python SDK"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "opentelemetry_sdk-1.41.1-py3-none-any.whl", hash = "sha256:edee379c126c1bce952b0c812b48fe8ff35b30df0eecf17e98afa4d598b7d85d"},
- {file = "opentelemetry_sdk-1.41.1.tar.gz", hash = "sha256:724b615e1215b5aeacda0abb8a6a8922c9a1853068948bd0bd225a56d0c792e6"},
-]
-
-[package.dependencies]
-opentelemetry-api = "1.41.1"
-opentelemetry-semantic-conventions = "0.62b1"
-typing-extensions = ">=4.5.0"
-
-[package.extras]
-file-configuration = ["jsonschema (>=4.0)", "pyyaml (>=6.0)"]
-
-[[package]]
-name = "opentelemetry-semantic-conventions"
-version = "0.62b1"
-description = "OpenTelemetry Semantic Conventions"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "opentelemetry_semantic_conventions-0.62b1-py3-none-any.whl", hash = "sha256:cf506938103d331fbb78eded0d9788095f7fd59016f2bda813c3324e5a74a93c"},
- {file = "opentelemetry_semantic_conventions-0.62b1.tar.gz", hash = "sha256:c5cc6e04a7f8c7cdd30be2ed81499fa4e75bfbd52c9cb70d40af1f9cd3619802"},
-]
-
-[package.dependencies]
-opentelemetry-api = "1.41.1"
-typing-extensions = ">=4.5.0"
-
-[[package]]
-name = "optuna"
-version = "4.6.0"
-description = "A hyperparameter optimization framework"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "optuna-4.6.0-py3-none-any.whl", hash = "sha256:4c3a9facdef2b2dd7e3e2a8ae3697effa70fae4056fcf3425cfc6f5a40feb069"},
- {file = "optuna-4.6.0.tar.gz", hash = "sha256:89e38c2447c7f793a726617b8043f01e31f0bad54855040db17eb3b49404a369"},
-]
-
-[package.dependencies]
-alembic = ">=1.5.0"
-colorlog = "*"
-numpy = "*"
-packaging = ">=20.0"
-PyYAML = "*"
-sqlalchemy = ">=1.4.2"
-tqdm = "*"
-
-[package.extras]
-benchmark = ["asv (>=0.5.0)", "cma", "virtualenv"]
-checking = ["black (<25.9.0)", "blackdoc (<0.4.2)", "flake8", "isort", "mypy", "mypy_boto3_s3", "scipy-stubs ; python_version >= \"3.10\"", "types-PyYAML", "types-redis", "types-setuptools", "types-tqdm", "typing_extensions (>=3.10.0.0)"]
-document = ["ase", "cmaes (>=0.12.0)", "fvcore", "kaleido (<0.4)", "lightgbm", "matplotlib (!=3.6.0)", "pandas", "pillow", "plotly (>=4.9.0)", "scikit-learn", "sphinx", "sphinx-copybutton", "sphinx-gallery", "sphinx-notfound-page", "sphinx_rtd_theme (>=1.2.0)", "torch", "torchvision"]
-optional = ["boto3", "cmaes (>=0.12.0)", "google-cloud-storage", "greenlet", "grpcio", "matplotlib (!=3.6.0)", "pandas", "plotly (>=4.9.0)", "protobuf (>=5.28.1)", "redis", "scikit-learn (>=0.24.2)", "scipy", "torch"]
-test = ["coverage", "fakeredis[lua]", "greenlet", "grpcio", "kaleido (<0.4)", "moto", "protobuf (>=5.28.1)", "pytest", "pytest-xdist", "scipy (>=1.9.2)", "torch"]
-
-[[package]]
-name = "orjson"
-version = "3.11.5"
-description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "orjson-3.11.5-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:df9eadb2a6386d5ea2bfd81309c505e125cfc9ba2b1b99a97e60985b0b3665d1"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc70da619744467d8f1f49a8cadae5ec7bbe054e5232d95f92ed8737f8c5870"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:073aab025294c2f6fc0807201c76fdaed86f8fc4be52c440fb78fbb759a1ac09"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:835f26fa24ba0bb8c53ae2a9328d1706135b74ec653ed933869b74b6909e63fd"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667c132f1f3651c14522a119e4dd631fad98761fa960c55e8e7430bb2a1ba4ac"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42e8961196af655bb5e63ce6c60d25e8798cd4dfbc04f4203457fa3869322c2e"},
- {file = "orjson-3.11.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75412ca06e20904c19170f8a24486c4e6c7887dea591ba18a1ab572f1300ee9f"},
- {file = "orjson-3.11.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6af8680328c69e15324b5af3ae38abbfcf9cbec37b5346ebfd52339c3d7e8a18"},
- {file = "orjson-3.11.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a86fe4ff4ea523eac8f4b57fdac319faf037d3c1be12405e6a7e86b3fbc4756a"},
- {file = "orjson-3.11.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e607b49b1a106ee2086633167033afbd63f76f2999e9236f638b06b112b24ea7"},
- {file = "orjson-3.11.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7339f41c244d0eea251637727f016b3d20050636695bc78345cce9029b189401"},
- {file = "orjson-3.11.5-cp310-cp310-win32.whl", hash = "sha256:8be318da8413cdbbce77b8c5fac8d13f6eb0f0db41b30bb598631412619572e8"},
- {file = "orjson-3.11.5-cp310-cp310-win_amd64.whl", hash = "sha256:b9f86d69ae822cabc2a0f6c099b43e8733dda788405cba2665595b7e8dd8d167"},
- {file = "orjson-3.11.5-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9c8494625ad60a923af6b2b0bd74107146efe9b55099e20d7740d995f338fcd8"},
- {file = "orjson-3.11.5-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:7bb2ce0b82bc9fd1168a513ddae7a857994b780b2945a8c51db4ab1c4b751ebc"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67394d3becd50b954c4ecd24ac90b5051ee7c903d167459f93e77fc6f5b4c968"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:298d2451f375e5f17b897794bcc3e7b821c0f32b4788b9bcae47ada24d7f3cf7"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa5e4244063db8e1d87e0f54c3f7522f14b2dc937e65d5241ef0076a096409fd"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1db2088b490761976c1b2e956d5d4e6409f3732e9d79cfa69f876c5248d1baf9"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2ed66358f32c24e10ceea518e16eb3549e34f33a9d51f99ce23b0251776a1ef"},
- {file = "orjson-3.11.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2021afda46c1ed64d74b555065dbd4c2558d510d8cec5ea6a53001b3e5e82a9"},
- {file = "orjson-3.11.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b42ffbed9128e547a1647a3e50bc88ab28ae9daa61713962e0d3dd35e820c125"},
- {file = "orjson-3.11.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8d5f16195bb671a5dd3d1dbea758918bada8f6cc27de72bd64adfbd748770814"},
- {file = "orjson-3.11.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c0e5d9f7a0227df2927d343a6e3859bebf9208b427c79bd31949abcc2fa32fa5"},
- {file = "orjson-3.11.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23d04c4543e78f724c4dfe656b3791b5f98e4c9253e13b2636f1af5d90e4a880"},
- {file = "orjson-3.11.5-cp311-cp311-win32.whl", hash = "sha256:c404603df4865f8e0afe981aa3c4b62b406e6d06049564d58934860b62b7f91d"},
- {file = "orjson-3.11.5-cp311-cp311-win_amd64.whl", hash = "sha256:9645ef655735a74da4990c24ffbd6894828fbfa117bc97c1edd98c282ecb52e1"},
- {file = "orjson-3.11.5-cp311-cp311-win_arm64.whl", hash = "sha256:1cbf2735722623fcdee8e712cbaaab9e372bbcb0c7924ad711b261c2eccf4a5c"},
- {file = "orjson-3.11.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d"},
- {file = "orjson-3.11.5-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa"},
- {file = "orjson-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477"},
- {file = "orjson-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e"},
- {file = "orjson-3.11.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69"},
- {file = "orjson-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3"},
- {file = "orjson-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca"},
- {file = "orjson-3.11.5-cp312-cp312-win32.whl", hash = "sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98"},
- {file = "orjson-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875"},
- {file = "orjson-3.11.5-cp312-cp312-win_arm64.whl", hash = "sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe"},
- {file = "orjson-3.11.5-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629"},
- {file = "orjson-3.11.5-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706"},
- {file = "orjson-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f"},
- {file = "orjson-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863"},
- {file = "orjson-3.11.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228"},
- {file = "orjson-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2"},
- {file = "orjson-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05"},
- {file = "orjson-3.11.5-cp313-cp313-win32.whl", hash = "sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef"},
- {file = "orjson-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583"},
- {file = "orjson-3.11.5-cp313-cp313-win_arm64.whl", hash = "sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287"},
- {file = "orjson-3.11.5-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0"},
- {file = "orjson-3.11.5-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4"},
- {file = "orjson-3.11.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad"},
- {file = "orjson-3.11.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829"},
- {file = "orjson-3.11.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac"},
- {file = "orjson-3.11.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d"},
- {file = "orjson-3.11.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439"},
- {file = "orjson-3.11.5-cp314-cp314-win32.whl", hash = "sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499"},
- {file = "orjson-3.11.5-cp314-cp314-win_amd64.whl", hash = "sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310"},
- {file = "orjson-3.11.5-cp314-cp314-win_arm64.whl", hash = "sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5"},
- {file = "orjson-3.11.5-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1b280e2d2d284a6713b0cfec7b08918ebe57df23e3f76b27586197afca3cb1e9"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c8d8a112b274fae8c5f0f01954cb0480137072c271f3f4958127b010dfefaec"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0a2ae6f09ac7bd47d2d5a5305c1d9ed08ac057cda55bb0a49fa506f0d2da00"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0d87bd1896faac0d10b4f849016db81a63e4ec5df38757ffae84d45ab38aa71"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:801a821e8e6099b8c459ac7540b3c32dba6013437c57fdcaec205b169754f38c"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a0f6ac618c98c74b7fbc8c0172ba86f9e01dbf9f62aa0b1776c2231a7bffe5"},
- {file = "orjson-3.11.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fea7339bdd22e6f1060c55ac31b6a755d86a5b2ad3657f2669ec243f8e3b2bdb"},
- {file = "orjson-3.11.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4dad582bc93cef8f26513e12771e76385a7e6187fd713157e971c784112aad56"},
- {file = "orjson-3.11.5-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:0522003e9f7fba91982e83a97fec0708f5a714c96c4209db7104e6b9d132f111"},
- {file = "orjson-3.11.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7403851e430a478440ecc1258bcbacbfbd8175f9ac1e39031a7121dd0de05ff8"},
- {file = "orjson-3.11.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5f691263425d3177977c8d1dd896cde7b98d93cbf390b2544a090675e83a6a0a"},
- {file = "orjson-3.11.5-cp39-cp39-win32.whl", hash = "sha256:61026196a1c4b968e1b1e540563e277843082e9e97d78afa03eb89315af531f1"},
- {file = "orjson-3.11.5-cp39-cp39-win_amd64.whl", hash = "sha256:09b94b947ac08586af635ef922d69dc9bc63321527a3a04647f4986a73f4bd30"},
- {file = "orjson-3.11.5.tar.gz", hash = "sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5"},
-]
-
-[[package]]
-name = "packaging"
-version = "24.2"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "eval", "test"]
-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.3.3"
-description = "Powerful data structures for data analysis, time series, and statistics"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "pandas-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c"},
- {file = "pandas-2.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a"},
- {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1"},
- {file = "pandas-2.3.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838"},
- {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250"},
- {file = "pandas-2.3.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4"},
- {file = "pandas-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826"},
- {file = "pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523"},
- {file = "pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45"},
- {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66"},
- {file = "pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b"},
- {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791"},
- {file = "pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151"},
- {file = "pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c"},
- {file = "pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53"},
- {file = "pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35"},
- {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908"},
- {file = "pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89"},
- {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98"},
- {file = "pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084"},
- {file = "pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b"},
- {file = "pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713"},
- {file = "pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8"},
- {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d"},
- {file = "pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac"},
- {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c"},
- {file = "pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493"},
- {file = "pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee"},
- {file = "pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5"},
- {file = "pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21"},
- {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78"},
- {file = "pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110"},
- {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86"},
- {file = "pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc"},
- {file = "pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0"},
- {file = "pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593"},
- {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c"},
- {file = "pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b"},
- {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6"},
- {file = "pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3"},
- {file = "pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5"},
- {file = "pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec"},
- {file = "pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7"},
- {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450"},
- {file = "pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5"},
- {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788"},
- {file = "pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87"},
- {file = "pandas-2.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2"},
- {file = "pandas-2.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8"},
- {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff"},
- {file = "pandas-2.3.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29"},
- {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73"},
- {file = "pandas-2.3.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9"},
- {file = "pandas-2.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa"},
- {file = "pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b"},
-]
-
-[package.dependencies]
-numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""}
-python-dateutil = ">=2.8.2"
-pytz = ">=2020.1"
-tzdata = ">=2022.7"
-
-[package.extras]
-all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"]
-aws = ["s3fs (>=2022.11.0)"]
-clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"]
-compression = ["zstandard (>=0.19.0)"]
-computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"]
-consortium-standard = ["dataframe-api-compat (>=0.1.7)"]
-excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"]
-feather = ["pyarrow (>=10.0.1)"]
-fss = ["fsspec (>=2022.11.0)"]
-gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"]
-hdf5 = ["tables (>=3.8.0)"]
-html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"]
-mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"]
-output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"]
-parquet = ["pyarrow (>=10.0.1)"]
-performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
-plot = ["matplotlib (>=3.6.3)"]
-postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
-pyarrow = ["pyarrow (>=10.0.1)"]
-spss = ["pyreadstat (>=1.2.0)"]
-sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
-test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
-xml = ["lxml (>=4.9.2)"]
-
-[[package]]
-name = "parso"
-version = "0.8.5"
-description = "A Python Parser"
-optional = false
-python-versions = ">=3.6"
-groups = ["eval"]
-files = [
- {file = "parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887"},
- {file = "parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a"},
-]
-
-[package.extras]
-qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"]
-testing = ["docopt", "pytest"]
-
-[[package]]
-name = "pexpect"
-version = "4.9.0"
-description = "Pexpect allows easy control of interactive console applications."
-optional = false
-python-versions = "*"
-groups = ["eval"]
-markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""
-files = [
- {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
- {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
-]
-
-[package.dependencies]
-ptyprocess = ">=0.5"
-
-[[package]]
-name = "pillow"
-version = "12.1.1"
-description = "Python Imaging Library (fork)"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"},
- {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"},
- {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"},
- {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"},
- {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"},
- {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"},
- {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"},
- {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"},
- {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"},
- {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"},
- {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"},
- {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"},
- {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"},
- {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"},
- {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"},
- {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"},
- {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"},
- {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"},
- {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"},
- {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"},
- {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"},
- {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"},
- {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"},
- {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"},
- {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"},
- {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"},
- {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"},
- {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"},
- {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"},
- {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"},
- {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"},
- {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"},
- {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"},
- {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"},
- {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"},
- {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"},
- {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"},
- {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"},
- {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"},
- {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"},
- {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"},
- {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"},
- {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"},
- {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"},
- {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"},
- {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"},
- {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"},
- {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"},
- {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"},
- {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"},
- {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"},
- {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"},
- {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"},
- {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"},
- {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"},
- {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"},
- {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"},
- {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"},
- {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"},
- {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"},
- {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"},
- {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"},
- {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"},
- {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"},
- {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"},
- {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"},
- {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"},
- {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"},
- {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"},
- {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"},
- {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"},
- {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"},
- {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"},
- {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"},
- {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"},
- {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"},
- {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"},
- {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"},
- {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"},
- {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"},
- {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"},
- {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"},
- {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"},
- {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"},
- {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"},
-]
-
-[package.extras]
-docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
-fpx = ["olefile"]
-mic = ["olefile"]
-test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"]
-tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
-xmp = ["defusedxml"]
-
-[[package]]
-name = "platformdirs"
-version = "4.5.0"
-description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
-optional = false
-python-versions = ">=3.10"
-groups = ["dev", "eval", "test"]
-files = [
- {file = "platformdirs-4.5.0-py3-none-any.whl", hash = "sha256:e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3"},
- {file = "platformdirs-4.5.0.tar.gz", hash = "sha256:70ddccdd7c99fc5942e9fc25636a8b34d04c24b335100223152c2803e4063312"},
-]
-
-[package.extras]
-docs = ["furo (>=2025.9.25)", "proselint (>=0.14)", "sphinx (>=8.2.3)", "sphinx-autodoc-typehints (>=3.2)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.4.2)", "pytest-cov (>=7)", "pytest-mock (>=3.15.1)"]
-type = ["mypy (>=1.18.2)"]
-
-[[package]]
-name = "plotly"
-version = "5.24.1"
-description = "An open-source, interactive data visualization library for Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089"},
- {file = "plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae"},
-]
-
-[package.dependencies]
-packaging = "*"
-tenacity = ">=6.2.0"
-
-[[package]]
-name = "pluggy"
-version = "1.6.0"
-description = "plugin and hook calling mechanisms for python"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "test"]
-files = [
- {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"},
- {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"},
-]
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["coverage", "pytest", "pytest-benchmark"]
-
-[[package]]
-name = "portalocker"
-version = "2.10.1"
-description = "Wraps the portalocker recipe for easy usage"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "portalocker-2.10.1-py3-none-any.whl", hash = "sha256:53a5984ebc86a025552264b459b46a2086e269b21823cb572f8f28ee759e45bf"},
- {file = "portalocker-2.10.1.tar.gz", hash = "sha256:ef1bf844e878ab08aee7e40184156e1151f228f103aa5c6bd0724cc330960f8f"},
-]
-
-[package.dependencies]
-pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""}
-
-[package.extras]
-docs = ["sphinx (>=1.7.1)"]
-redis = ["redis"]
-tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)", "types-redis"]
-
-[[package]]
-name = "posthog"
-version = "5.4.0"
-description = "Integrate PostHog into any python application."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "posthog-5.4.0-py3-none-any.whl", hash = "sha256:284dfa302f64353484420b52d4ad81ff5c2c2d1d607c4e2db602ac72761831bd"},
- {file = "posthog-5.4.0.tar.gz", hash = "sha256:701669261b8d07cdde0276e5bc096b87f9e200e3b9589c5ebff14df658c5893c"},
-]
-
-[package.dependencies]
-backoff = ">=1.10.0"
-distro = ">=1.5.0"
-python-dateutil = ">=2.2"
-requests = ">=2.7,<3.0"
-six = ">=1.5"
-
-[package.extras]
-dev = ["django-stubs", "lxml", "mypy", "mypy-baseline", "packaging", "pre-commit", "pydantic", "ruff", "setuptools", "tomli", "tomli_w", "twine", "types-mock", "types-python-dateutil", "types-requests", "types-setuptools", "types-six", "wheel"]
-langchain = ["langchain (>=0.2.0)"]
-test = ["anthropic", "coverage", "django", "freezegun (==1.5.1)", "google-genai", "langchain-anthropic (>=0.3.15)", "langchain-community (>=0.3.25)", "langchain-core (>=0.3.65)", "langchain-openai (>=0.3.22)", "langgraph (>=0.4.8)", "mock (>=2.0.0)", "openai", "parameterized (>=0.8.1)", "pydantic", "pytest", "pytest-asyncio", "pytest-timeout"]
-
-[[package]]
-name = "pre-commit"
-version = "3.8.0"
-description = "A framework for managing and maintaining multi-language pre-commit hooks."
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"},
- {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"},
-]
-
-[package.dependencies]
-cfgv = ">=2.0.0"
-identify = ">=1.0.0"
-nodeenv = ">=0.11.1"
-pyyaml = ">=5.1"
-virtualenv = ">=20.10.0"
-
-[[package]]
-name = "prompt-toolkit"
-version = "3.0.52"
-description = "Library for building powerful interactive command lines in Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955"},
- {file = "prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855"},
-]
-
-[package.dependencies]
-wcwidth = "*"
-
-[[package]]
-name = "propcache"
-version = "0.4.1"
-description = "Accelerated property cache"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "propcache-0.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db"},
- {file = "propcache-0.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8"},
- {file = "propcache-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925"},
- {file = "propcache-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21"},
- {file = "propcache-0.4.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5"},
- {file = "propcache-0.4.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db"},
- {file = "propcache-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7"},
- {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4"},
- {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60"},
- {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f"},
- {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900"},
- {file = "propcache-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c"},
- {file = "propcache-0.4.1-cp310-cp310-win32.whl", hash = "sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb"},
- {file = "propcache-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37"},
- {file = "propcache-0.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581"},
- {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf"},
- {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5"},
- {file = "propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e"},
- {file = "propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566"},
- {file = "propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165"},
- {file = "propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc"},
- {file = "propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48"},
- {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570"},
- {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85"},
- {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e"},
- {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757"},
- {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f"},
- {file = "propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1"},
- {file = "propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6"},
- {file = "propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239"},
- {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2"},
- {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403"},
- {file = "propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207"},
- {file = "propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72"},
- {file = "propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367"},
- {file = "propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4"},
- {file = "propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf"},
- {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3"},
- {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778"},
- {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6"},
- {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9"},
- {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75"},
- {file = "propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8"},
- {file = "propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db"},
- {file = "propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1"},
- {file = "propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf"},
- {file = "propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311"},
- {file = "propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74"},
- {file = "propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe"},
- {file = "propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af"},
- {file = "propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c"},
- {file = "propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f"},
- {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1"},
- {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24"},
- {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa"},
- {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61"},
- {file = "propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66"},
- {file = "propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81"},
- {file = "propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e"},
- {file = "propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1"},
- {file = "propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b"},
- {file = "propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566"},
- {file = "propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835"},
- {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e"},
- {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859"},
- {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b"},
- {file = "propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0"},
- {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af"},
- {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393"},
- {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874"},
- {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7"},
- {file = "propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1"},
- {file = "propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717"},
- {file = "propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37"},
- {file = "propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a"},
- {file = "propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12"},
- {file = "propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c"},
- {file = "propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded"},
- {file = "propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641"},
- {file = "propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4"},
- {file = "propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44"},
- {file = "propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d"},
- {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b"},
- {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e"},
- {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f"},
- {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49"},
- {file = "propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144"},
- {file = "propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f"},
- {file = "propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153"},
- {file = "propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992"},
- {file = "propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f"},
- {file = "propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393"},
- {file = "propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0"},
- {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a"},
- {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be"},
- {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc"},
- {file = "propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a"},
- {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89"},
- {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726"},
- {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367"},
- {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36"},
- {file = "propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455"},
- {file = "propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85"},
- {file = "propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1"},
- {file = "propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9"},
- {file = "propcache-0.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff"},
- {file = "propcache-0.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb"},
- {file = "propcache-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac"},
- {file = "propcache-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888"},
- {file = "propcache-0.4.1-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc"},
- {file = "propcache-0.4.1-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a"},
- {file = "propcache-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88"},
- {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00"},
- {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0"},
- {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e"},
- {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781"},
- {file = "propcache-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183"},
- {file = "propcache-0.4.1-cp39-cp39-win32.whl", hash = "sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19"},
- {file = "propcache-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f"},
- {file = "propcache-0.4.1-cp39-cp39-win_arm64.whl", hash = "sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938"},
- {file = "propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237"},
- {file = "propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d"},
-]
-
-[[package]]
-name = "protobuf"
-version = "6.33.5"
-description = ""
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "protobuf-6.33.5-cp310-abi3-win32.whl", hash = "sha256:d71b040839446bac0f4d162e758bea99c8251161dae9d0983a3b88dee345153b"},
- {file = "protobuf-6.33.5-cp310-abi3-win_amd64.whl", hash = "sha256:3093804752167bcab3998bec9f1048baae6e29505adaf1afd14a37bddede533c"},
- {file = "protobuf-6.33.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a5cb85982d95d906df1e2210e58f8e4f1e3cdc088e52c921a041f9c9a0386de5"},
- {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:9b71e0281f36f179d00cbcb119cb19dec4d14a81393e5ea220f64b286173e190"},
- {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:8afa18e1d6d20af15b417e728e9f60f3aa108ee76f23c3b2c07a2c3b546d3afd"},
- {file = "protobuf-6.33.5-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:cbf16ba3350fb7b889fca858fb215967792dc125b35c7976ca4818bee3521cf0"},
- {file = "protobuf-6.33.5-cp39-cp39-win32.whl", hash = "sha256:a3157e62729aafb8df6da2c03aa5c0937c7266c626ce11a278b6eb7963c4e37c"},
- {file = "protobuf-6.33.5-cp39-cp39-win_amd64.whl", hash = "sha256:8f04fa32763dcdb4973d537d6b54e615cc61108c7cb38fe59310c3192d29510a"},
- {file = "protobuf-6.33.5-py3-none-any.whl", hash = "sha256:69915a973dd0f60f31a08b8318b73eab2bd6a392c79184b3612226b0a3f8ec02"},
- {file = "protobuf-6.33.5.tar.gz", hash = "sha256:6ddcac2a081f8b7b9642c09406bc6a4290128fce5f471cddd165960bb9119e5c"},
-]
-
-[[package]]
-name = "psutil"
-version = "7.1.3"
-description = "Cross-platform lib for process and system monitoring."
-optional = false
-python-versions = ">=3.6"
-groups = ["eval", "test"]
-files = [
- {file = "psutil-7.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0005da714eee687b4b8decd3d6cc7c6db36215c9e74e5ad2264b90c3df7d92dc"},
- {file = "psutil-7.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19644c85dcb987e35eeeaefdc3915d059dac7bd1167cdcdbf27e0ce2df0c08c0"},
- {file = "psutil-7.1.3-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95ef04cf2e5ba0ab9eaafc4a11eaae91b44f4ef5541acd2ee91d9108d00d59a7"},
- {file = "psutil-7.1.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1068c303be3a72f8e18e412c5b2a8f6d31750fb152f9cb106b54090296c9d251"},
- {file = "psutil-7.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:18349c5c24b06ac5612c0428ec2a0331c26443d259e2a0144a9b24b4395b58fa"},
- {file = "psutil-7.1.3-cp313-cp313t-win_arm64.whl", hash = "sha256:c525ffa774fe4496282fb0b1187725793de3e7c6b29e41562733cae9ada151ee"},
- {file = "psutil-7.1.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b403da1df4d6d43973dc004d19cee3b848e998ae3154cc8097d139b77156c353"},
- {file = "psutil-7.1.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad81425efc5e75da3f39b3e636293360ad8d0b49bed7df824c79764fb4ba9b8b"},
- {file = "psutil-7.1.3-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f33a3702e167783a9213db10ad29650ebf383946e91bc77f28a5eb083496bc9"},
- {file = "psutil-7.1.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fac9cd332c67f4422504297889da5ab7e05fd11e3c4392140f7370f4208ded1f"},
- {file = "psutil-7.1.3-cp314-cp314t-win_amd64.whl", hash = "sha256:3792983e23b69843aea49c8f5b8f115572c5ab64c153bada5270086a2123c7e7"},
- {file = "psutil-7.1.3-cp314-cp314t-win_arm64.whl", hash = "sha256:31d77fcedb7529f27bb3a0472bea9334349f9a04160e8e6e5020f22c59893264"},
- {file = "psutil-7.1.3-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2bdbcd0e58ca14996a42adf3621a6244f1bb2e2e528886959c72cf1e326677ab"},
- {file = "psutil-7.1.3-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:bc31fa00f1fbc3c3802141eede66f3a2d51d89716a194bf2cd6fc68310a19880"},
- {file = "psutil-7.1.3-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3bb428f9f05c1225a558f53e30ccbad9930b11c3fc206836242de1091d3e7dd3"},
- {file = "psutil-7.1.3-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d974e02ca2c8eb4812c3f76c30e28836fffc311d55d979f1465c1feeb2b68b"},
- {file = "psutil-7.1.3-cp37-abi3-win_amd64.whl", hash = "sha256:f39c2c19fe824b47484b96f9692932248a54c43799a84282cfe58d05a6449efd"},
- {file = "psutil-7.1.3-cp37-abi3-win_arm64.whl", hash = "sha256:bd0d69cee829226a761e92f28140bec9a5ee9d5b4fb4b0cc589068dbfff559b1"},
- {file = "psutil-7.1.3.tar.gz", hash = "sha256:6c86281738d77335af7aec228328e944b30930899ea760ecf33a4dba66be5e74"},
-]
-
-[package.extras]
-dev = ["abi3audit", "black", "check-manifest", "colorama ; os_name == \"nt\"", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pyreadline ; os_name == \"nt\"", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "requests", "rstcheck", "ruff", "setuptools", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "validate-pyproject[all]", "virtualenv", "vulture", "wheel", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""]
-test = ["pytest", "pytest-instafail", "pytest-subtests", "pytest-xdist", "pywin32 ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "setuptools", "wheel ; os_name == \"nt\" and platform_python_implementation != \"PyPy\"", "wmi ; os_name == \"nt\" and platform_python_implementation != \"PyPy\""]
-
-[[package]]
-name = "psycopg2"
-version = "2.9.11"
-description = "psycopg2 - Python-PostgreSQL Database Adapter"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "psycopg2-2.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:103e857f46bb76908768ead4e2d0ba1d1a130e7b8ed77d3ae91e8b33481813e8"},
- {file = "psycopg2-2.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:210daed32e18f35e3140a1ebe059ac29209dd96468f2f7559aa59f75ee82a5cb"},
- {file = "psycopg2-2.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:e03e4a6dbe87ff81540b434f2e5dc2bddad10296db5eea7bdc995bf5f4162938"},
- {file = "psycopg2-2.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:8dc379166b5b7d5ea66dcebf433011dfc51a7bb8a5fc12367fa05668e5fc53c8"},
- {file = "psycopg2-2.9.11-cp314-cp314-win_amd64.whl", hash = "sha256:f10a48acba5fe6e312b891f290b4d2ca595fc9a06850fe53320beac353575578"},
- {file = "psycopg2-2.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:6ecddcf573777536bddfefaea8079ce959287798c8f5804bee6933635d538924"},
- {file = "psycopg2-2.9.11.tar.gz", hash = "sha256:964d31caf728e217c697ff77ea69c2ba0865fa41ec20bb00f0977e62fdcc52e3"},
-]
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-description = "Run a subprocess in a pseudo terminal"
-optional = false
-python-versions = "*"
-groups = ["eval"]
-markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""
-files = [
- {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
- {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-
-[[package]]
-name = "pure-eval"
-version = "0.2.3"
-description = "Safely evaluate AST nodes without side effects"
-optional = false
-python-versions = "*"
-groups = ["eval"]
-files = [
- {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"},
- {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"},
-]
-
-[package.extras]
-tests = ["pytest"]
-
-[[package]]
-name = "pyarrow"
-version = "21.0.0"
-description = "Python library for Apache Arrow"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "eval"]
-files = [
- {file = "pyarrow-21.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:e563271e2c5ff4d4a4cbeb2c83d5cf0d4938b891518e676025f7268c6fe5fe26"},
- {file = "pyarrow-21.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:fee33b0ca46f4c85443d6c450357101e47d53e6c3f008d658c27a2d020d44c79"},
- {file = "pyarrow-21.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:7be45519b830f7c24b21d630a31d48bcebfd5d4d7f9d3bdb49da9cdf6d764edb"},
- {file = "pyarrow-21.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:26bfd95f6bff443ceae63c65dc7e048670b7e98bc892210acba7e4995d3d4b51"},
- {file = "pyarrow-21.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bd04ec08f7f8bd113c55868bd3fc442a9db67c27af098c5f814a3091e71cc61a"},
- {file = "pyarrow-21.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9b0b14b49ac10654332a805aedfc0147fb3469cbf8ea951b3d040dab12372594"},
- {file = "pyarrow-21.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:9d9f8bcb4c3be7738add259738abdeddc363de1b80e3310e04067aa1ca596634"},
- {file = "pyarrow-21.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c077f48aab61738c237802836fc3844f85409a46015635198761b0d6a688f87b"},
- {file = "pyarrow-21.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:689f448066781856237eca8d1975b98cace19b8dd2ab6145bf49475478bcaa10"},
- {file = "pyarrow-21.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:479ee41399fcddc46159a551705b89c05f11e8b8cb8e968f7fec64f62d91985e"},
- {file = "pyarrow-21.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:40ebfcb54a4f11bcde86bc586cbd0272bac0d516cfa539c799c2453768477569"},
- {file = "pyarrow-21.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8d58d8497814274d3d20214fbb24abcad2f7e351474357d552a8d53bce70c70e"},
- {file = "pyarrow-21.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:585e7224f21124dd57836b1530ac8f2df2afc43c861d7bf3d58a4870c42ae36c"},
- {file = "pyarrow-21.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:555ca6935b2cbca2c0e932bedd853e9bc523098c39636de9ad4693b5b1df86d6"},
- {file = "pyarrow-21.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3a302f0e0963db37e0a24a70c56cf91a4faa0bca51c23812279ca2e23481fccd"},
- {file = "pyarrow-21.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:b6b27cf01e243871390474a211a7922bfbe3bda21e39bc9160daf0da3fe48876"},
- {file = "pyarrow-21.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:e72a8ec6b868e258a2cd2672d91f2860ad532d590ce94cdf7d5e7ec674ccf03d"},
- {file = "pyarrow-21.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b7ae0bbdc8c6674259b25bef5d2a1d6af5d39d7200c819cf99e07f7dfef1c51e"},
- {file = "pyarrow-21.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:58c30a1729f82d201627c173d91bd431db88ea74dcaa3885855bc6203e433b82"},
- {file = "pyarrow-21.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:072116f65604b822a7f22945a7a6e581cfa28e3454fdcc6939d4ff6090126623"},
- {file = "pyarrow-21.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:cf56ec8b0a5c8c9d7021d6fd754e688104f9ebebf1bf4449613c9531f5346a18"},
- {file = "pyarrow-21.0.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:e99310a4ebd4479bcd1964dff9e14af33746300cb014aa4a3781738ac63baf4a"},
- {file = "pyarrow-21.0.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:d2fe8e7f3ce329a71b7ddd7498b3cfac0eeb200c2789bd840234f0dc271a8efe"},
- {file = "pyarrow-21.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:f522e5709379d72fb3da7785aa489ff0bb87448a9dc5a75f45763a795a089ebd"},
- {file = "pyarrow-21.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:69cbbdf0631396e9925e048cfa5bce4e8c3d3b41562bbd70c685a8eb53a91e61"},
- {file = "pyarrow-21.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:731c7022587006b755d0bdb27626a1a3bb004bb56b11fb30d98b6c1b4718579d"},
- {file = "pyarrow-21.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc56bc708f2d8ac71bd1dcb927e458c93cec10b98eb4120206a4091db7b67b99"},
- {file = "pyarrow-21.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:186aa00bca62139f75b7de8420f745f2af12941595bbbfa7ed3870ff63e25636"},
- {file = "pyarrow-21.0.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:a7a102574faa3f421141a64c10216e078df467ab9576684d5cd696952546e2da"},
- {file = "pyarrow-21.0.0-cp313-cp313t-macosx_12_0_x86_64.whl", hash = "sha256:1e005378c4a2c6db3ada3ad4c217b381f6c886f0a80d6a316fe586b90f77efd7"},
- {file = "pyarrow-21.0.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:65f8e85f79031449ec8706b74504a316805217b35b6099155dd7e227eef0d4b6"},
- {file = "pyarrow-21.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:3a81486adc665c7eb1a2bde0224cfca6ceaba344a82a971ef059678417880eb8"},
- {file = "pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fc0d2f88b81dcf3ccf9a6ae17f89183762c8a94a5bdcfa09e05cfe413acf0503"},
- {file = "pyarrow-21.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6299449adf89df38537837487a4f8d3bd91ec94354fdd2a7d30bc11c48ef6e79"},
- {file = "pyarrow-21.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:222c39e2c70113543982c6b34f3077962b44fca38c0bd9e68bb6781534425c10"},
- {file = "pyarrow-21.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:a7f6524e3747e35f80744537c78e7302cd41deee8baa668d56d55f77d9c464b3"},
- {file = "pyarrow-21.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:203003786c9fd253ebcafa44b03c06983c9c8d06c3145e37f1b76a1f317aeae1"},
- {file = "pyarrow-21.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b4d97e297741796fead24867a8dabf86c87e4584ccc03167e4a811f50fdf74d"},
- {file = "pyarrow-21.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:898afce396b80fdda05e3086b4256f8677c671f7b1d27a6976fa011d3fd0a86e"},
- {file = "pyarrow-21.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:067c66ca29aaedae08218569a114e413b26e742171f526e828e1064fcdec13f4"},
- {file = "pyarrow-21.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0c4e75d13eb76295a49e0ea056eb18dbd87d81450bfeb8afa19a7e5a75ae2ad7"},
- {file = "pyarrow-21.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdc4c17afda4dab2a9c0b79148a43a7f4e1094916b3e18d8975bfd6d6d52241f"},
- {file = "pyarrow-21.0.0.tar.gz", hash = "sha256:5051f2dccf0e283ff56335760cbc8622cf52264d67e359d5569541ac11b6d5bc"},
-]
-
-[package.extras]
-test = ["cffi", "hypothesis", "pandas", "pytest", "pytz"]
-
-[[package]]
-name = "pyasn1"
-version = "0.6.2"
-description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "pyasn1-0.6.2-py3-none-any.whl", hash = "sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf"},
- {file = "pyasn1-0.6.2.tar.gz", hash = "sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b"},
-]
-
-[[package]]
-name = "pyasn1-modules"
-version = "0.4.2"
-description = "A collection of ASN.1-based protocols modules"
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"},
- {file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"},
-]
-
-[package.dependencies]
-pyasn1 = ">=0.6.1,<0.7.0"
-
-[[package]]
-name = "pycares"
-version = "4.11.0"
-description = "Python interface for c-ares"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "pycares-4.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87dab618fe116f1936f8461df5970fcf0befeba7531a36b0a86321332ff9c20b"},
- {file = "pycares-4.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3db6b6439e378115572fa317053f3ee6eecb39097baafe9292320ff1a9df73e3"},
- {file = "pycares-4.11.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:742fbaa44b418237dbd6bf8cdab205c98b3edb334436a972ad341b0ea296fb47"},
- {file = "pycares-4.11.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:d2a3526dbf6cb01b355e8867079c9356a8df48706b4b099ac0bf59d4656e610d"},
- {file = "pycares-4.11.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:3d5300a598ad48bbf169fba1f2b2e4cf7ab229e7c1a48d8c1166f9ccf1755cb3"},
- {file = "pycares-4.11.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:066f3caa07c85e1a094aebd9e7a7bb3f3b2d97cff2276665693dd5c0cc81cf84"},
- {file = "pycares-4.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dcd4a7761fdfb5aaac88adad0a734dd065c038f5982a8c4b0dd28efa0bd9cc7c"},
- {file = "pycares-4.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:83a7401d7520fa14b00d85d68bcca47a0676c69996e8515d53733972286f9739"},
- {file = "pycares-4.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:66c310773abe42479302abf064832f4a37c8d7f788f4d5ee0d43cbad35cf5ff4"},
- {file = "pycares-4.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:95bc81f83fadb67f7f87914f216a0e141555ee17fd7f56e25aa0cc165e99e53b"},
- {file = "pycares-4.11.0-cp310-cp310-win32.whl", hash = "sha256:1dbbf0cfb39be63598b4cdc2522960627bf2f523e49c4349fb64b0499902ec7c"},
- {file = "pycares-4.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dde02314eefb85dce3cfdd747e8b44c69a94d442c0d7221b7de151ee4c93f0f5"},
- {file = "pycares-4.11.0-cp310-cp310-win_arm64.whl", hash = "sha256:9518514e3e85646bac798d94d34bf5b8741ee0cb580512e8450ce884f526b7cf"},
- {file = "pycares-4.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c2971af3a4094280f7c24293ff4d361689c175c1ebcbea6b3c1560eaff7cb240"},
- {file = "pycares-4.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5d69e2034160e1219665decb8140e439afc7a7afcfd4adff08eb0f6142405c3e"},
- {file = "pycares-4.11.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3bd81ad69f607803f531ff5cfa1262391fa06e78488c13495cee0f70d02e0287"},
- {file = "pycares-4.11.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:0aed0974eab3131d832e7e84a73ddb0dddbc57393cd8c0788d68a759a78c4a7b"},
- {file = "pycares-4.11.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:30d197180af626bb56f17e1fa54640838d7d12ed0f74665a3014f7155435b199"},
- {file = "pycares-4.11.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cb711a66246561f1cae51244deef700eef75481a70d99611fd3c8ab5bd69ab49"},
- {file = "pycares-4.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7aba9a312a620052133437f2363aae90ae4695ee61cb2ee07cbb9951d4c69ddd"},
- {file = "pycares-4.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c2af7a9d3afb63da31df1456d38b91555a6c147710a116d5cc70ab1e9f457a4f"},
- {file = "pycares-4.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d5fe089be67bc5927f0c0bd60c082c79f22cf299635ee3ddd370ae2a6e8b4ae0"},
- {file = "pycares-4.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35ff1ec260372c97ed688efd5b3c6e5481f2274dea08f6c4ea864c195a9673c6"},
- {file = "pycares-4.11.0-cp311-cp311-win32.whl", hash = "sha256:ff3d25883b7865ea34c00084dd22a7be7c58fd3131db6b25c35eafae84398f9d"},
- {file = "pycares-4.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:f4695153333607e63068580f2979b377b641a03bc36e02813659ffbea2b76fe2"},
- {file = "pycares-4.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:dc54a21586c096df73f06f9bdf594e8d86d7be84e5d4266358ce81c04c3cc88c"},
- {file = "pycares-4.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b93d624560ba52287873bacff70b42c99943821ecbc810b959b0953560f53c36"},
- {file = "pycares-4.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:775d99966e28c8abd9910ddef2de0f1e173afc5a11cea9f184613c747373ab80"},
- {file = "pycares-4.11.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:84fde689557361764f052850a2d68916050adbfd9321f6105aca1d8f1a9bd49b"},
- {file = "pycares-4.11.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:30ceed06f3bf5eff865a34d21562c25a7f3dad0ed336b9dd415330e03a6c50c4"},
- {file = "pycares-4.11.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:97d971b3a88a803bb95ff8a40ea4d68da59319eb8b59e924e318e2560af8c16d"},
- {file = "pycares-4.11.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2d5cac829da91ade70ce1af97dad448c6cd4778b48facbce1b015e16ced93642"},
- {file = "pycares-4.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee1ea367835eb441d246164c09d1f9703197af4425fc6865cefcde9e2ca81f85"},
- {file = "pycares-4.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3139ec1f4450a4b253386035c5ecd2722582ae3320a456df5021ffe3f174260a"},
- {file = "pycares-4.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5d70324ca1d82c6c4b00aa678347f7560d1ef2ce1d181978903459a97751543a"},
- {file = "pycares-4.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e2f8d9cfe0eb3a2997fde5df99b1aaea5a46dabfcfcac97b2d05f027c2cd5e28"},
- {file = "pycares-4.11.0-cp312-cp312-win32.whl", hash = "sha256:1571a7055c03a95d5270c914034eac7f8bfa1b432fc1de53d871b821752191a4"},
- {file = "pycares-4.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:7570e0b50db619b2ee370461c462617225dc3a3f63f975c6f117e2f0c94f82ca"},
- {file = "pycares-4.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:f199702740f3b766ed8c70efb885538be76cb48cd0cb596b948626f0b825e07a"},
- {file = "pycares-4.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2c296ab94d1974f8d2f76c499755a9ce31ffd4986e8898ef19b90e32525f7d84"},
- {file = "pycares-4.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0fcd3a8bac57a0987d9b09953ba0f8703eb9dca7c77f7051d8c2ed001185be8"},
- {file = "pycares-4.11.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:bac55842047567ddae177fb8189b89a60633ac956d5d37260f7f71b517fd8b87"},
- {file = "pycares-4.11.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:4da2e805ed8c789b9444ef4053f6ef8040cd13b0c1ca6d3c4fe6f9369c458cb4"},
- {file = "pycares-4.11.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:ea785d1f232b42b325578f0c8a2fa348192e182cc84a1e862896076a4a2ba2a7"},
- {file = "pycares-4.11.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:aa160dc9e785212c49c12bb891e242c949758b99542946cc8e2098ef391f93b0"},
- {file = "pycares-4.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7830709c23bbc43fbaefbb3dde57bdd295dc86732504b9d2e65044df8fd5e9fb"},
- {file = "pycares-4.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ef1ab7abbd238bb2dbbe871c3ea39f5a7fc63547c015820c1e24d0d494a1689"},
- {file = "pycares-4.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a4060d8556c908660512d42df1f4a874e4e91b81f79e3a9090afedc7690ea5ba"},
- {file = "pycares-4.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a98fac4a3d4f780817016b6f00a8a2c2f41df5d25dfa8e5b1aa0d783645a6566"},
- {file = "pycares-4.11.0-cp313-cp313-win32.whl", hash = "sha256:faa8321bc2a366189dcf87b3823e030edf5ac97a6b9a7fc99f1926c4bf8ef28e"},
- {file = "pycares-4.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:6f74b1d944a50fa12c5006fd10b45e1a45da0c5d15570919ce48be88e428264c"},
- {file = "pycares-4.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f7581793d8bb3014028b8397f6f80b99db8842da58f4409839c29b16397ad"},
- {file = "pycares-4.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:df0a17f4e677d57bca3624752bbb515316522ad1ce0de07ed9d920e6c4ee5d35"},
- {file = "pycares-4.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3b44e54cad31d3c3be5e8149ac36bc1c163ec86e0664293402f6f846fb22ad00"},
- {file = "pycares-4.11.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:80752133442dc7e6dd9410cec227c49f69283c038c316a8585cca05ec32c2766"},
- {file = "pycares-4.11.0-cp314-cp314-manylinux_2_28_ppc64le.whl", hash = "sha256:84b0b402dd333403fdce0e204aef1ef834d839c439c0c1aa143dc7d1237bb197"},
- {file = "pycares-4.11.0-cp314-cp314-manylinux_2_28_s390x.whl", hash = "sha256:c0eec184df42fc82e43197e073f9cc8f93b25ad2f11f230c64c2dc1c80dbc078"},
- {file = "pycares-4.11.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ee751409322ff10709ee867d5aea1dc8431eec7f34835f0f67afd016178da134"},
- {file = "pycares-4.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1732db81e348bfce19c9bf9448ba660aea03042eeeea282824da1604a5bd4dcf"},
- {file = "pycares-4.11.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:702d21823996f139874aba5aa9bb786d69e93bde6e3915b99832eb4e335d31ae"},
- {file = "pycares-4.11.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:218619b912cef7c64a339ab0e231daea10c994a05699740714dff8c428b9694a"},
- {file = "pycares-4.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:719f7ddff024fdacde97b926b4b26d0cc25901d5ef68bb994a581c420069936d"},
- {file = "pycares-4.11.0-cp314-cp314-win32.whl", hash = "sha256:d552fb2cb513ce910d1dc22dbba6420758a991a356f3cd1b7ec73a9e31f94d01"},
- {file = "pycares-4.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:23d50a0842e8dbdddf870a7218a7ab5053b68892706b3a391ecb3d657424d266"},
- {file = "pycares-4.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:836725754c32363d2c5d15b931b3ebd46b20185c02e850672cb6c5f0452c1e80"},
- {file = "pycares-4.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c9d839b5700542b27c1a0d359cbfad6496341e7c819c7fea63db9588857065ed"},
- {file = "pycares-4.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:31b85ad00422b38f426e5733a71dfb7ee7eb65a99ea328c508d4f552b1760dc8"},
- {file = "pycares-4.11.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:cdac992206756b024b371760c55719eb5cd9d6b2cb25a8d5a04ae1b0ff426232"},
- {file = "pycares-4.11.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:ffb22cee640bc12ee0e654eba74ecfb59e2e0aebc5bccc3cc7ef92f487008af7"},
- {file = "pycares-4.11.0-cp314-cp314t-manylinux_2_28_s390x.whl", hash = "sha256:00538826d2eaf4a0e4becb0753b0ac8d652334603c445c9566c9eb273657eb4c"},
- {file = "pycares-4.11.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:29daa36548c04cdcd1a78ae187a4b7b003f0b357a2f4f1f98f9863373eedc759"},
- {file = "pycares-4.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:cf306f3951740d7bed36149a6d8d656a7d5432dd4bbc6af3bb6554361fc87401"},
- {file = "pycares-4.11.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:386da2581db4ea2832629e275c061103b0be32f9391c5dfaea7f6040951950ad"},
- {file = "pycares-4.11.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:45d3254a694459fdb0640ef08724ca9d4b4f6ff6d7161c9b526d7d2e2111379e"},
- {file = "pycares-4.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eddf5e520bb88b23b04ac1f28f5e9a7c77c718b8b4af3a4a7a2cc4a600f34502"},
- {file = "pycares-4.11.0-cp314-cp314t-win32.whl", hash = "sha256:8a75a406432ce39ce0ca41edff7486df6c970eb0fe5cfbe292f195a6b8654461"},
- {file = "pycares-4.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3784b80d797bcc2ff2bf3d4b27f46d8516fe1707ff3b82c2580dc977537387f9"},
- {file = "pycares-4.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:afc6503adf8b35c21183b9387be64ca6810644ef54c9ef6c99d1d5635c01601b"},
- {file = "pycares-4.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5e1ab899bb0763dea5d6569300aab3a205572e6e2d0ef1a33b8cf2b86d1312a4"},
- {file = "pycares-4.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9d0c543bdeefa4794582ef48f3c59e5e7a43d672a4bfad9cbbd531e897911690"},
- {file = "pycares-4.11.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5344d52efa37df74728505a81dd52c15df639adffd166f7ddca7a6318ecdb605"},
- {file = "pycares-4.11.0-cp39-cp39-manylinux_2_28_ppc64le.whl", hash = "sha256:b50ca218a3e2e23cbda395fd002d030385202fbb8182aa87e11bea0a568bd0b8"},
- {file = "pycares-4.11.0-cp39-cp39-manylinux_2_28_s390x.whl", hash = "sha256:30feeab492ac609f38a0d30fab3dc1789bd19c48f725b2955bcaaef516e32a21"},
- {file = "pycares-4.11.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:6195208b16cce1a7b121727710a6f78e8403878c1017ab5a3f92158b048cec34"},
- {file = "pycares-4.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:77bf82dc0beb81262bf1c7f546e1c1fde4992e5c8a2343b867ca201b85f9e1aa"},
- {file = "pycares-4.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:aca981fc00c8af8d5b9254ea5c2f276df8ece089b081af1ef4856fbcfc7c698a"},
- {file = "pycares-4.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:96e07d5a8b733d753e37d1f7138e7321d2316bb3f0f663ab4e3d500fabc82807"},
- {file = "pycares-4.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9a00408105901ede92e318eecb46d0e661d7d093d0a9b1224c71b5dd94f79e83"},
- {file = "pycares-4.11.0-cp39-cp39-win32.whl", hash = "sha256:910ce19a549f493fb55cfd1d7d70960706a03de6bfc896c1429fc5d6216df77e"},
- {file = "pycares-4.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:6f751f5a0e4913b2787f237c2c69c11a53f599269012feaa9fb86d7cef3aec26"},
- {file = "pycares-4.11.0-cp39-cp39-win_arm64.whl", hash = "sha256:f6c602c5e3615abbf43dbdf3c6c64c65e76e5aa23cb74e18466b55d4a2095468"},
- {file = "pycares-4.11.0.tar.gz", hash = "sha256:c863d9003ca0ce7df26429007859afd2a621d3276ed9fef154a9123db9252557"},
-]
-
-[package.dependencies]
-cffi = {version = ">=1.5.0", markers = "python_version < \"3.14\""}
-
-[package.extras]
-idna = ["idna (>=2.1)"]
-
-[[package]]
-name = "pycparser"
-version = "2.23"
-description = "C parser in Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "eval", "test"]
-files = [
- {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"},
- {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"},
-]
-markers = {main = "implementation_name != \"PyPy\"", eval = "implementation_name == \"pypy\"", test = "platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and implementation_name != \"PyPy\" or implementation_name == \"pypy\""}
-
-[[package]]
-name = "pydantic"
-version = "2.12.5"
-description = "Data validation using Python type hints"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d"},
- {file = "pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49"},
-]
-
-[package.dependencies]
-annotated-types = ">=0.6.0"
-pydantic-core = "2.41.5"
-typing-extensions = ">=4.14.1"
-typing-inspection = ">=0.4.2"
-
-[package.extras]
-email = ["email-validator (>=2.0.0)"]
-timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""]
-
-[[package]]
-name = "pydantic-core"
-version = "2.41.5"
-description = "Core functionality for Pydantic validation and serialization"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146"},
- {file = "pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a"},
- {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c"},
- {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2"},
- {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556"},
- {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49"},
- {file = "pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba"},
- {file = "pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9"},
- {file = "pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6"},
- {file = "pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b"},
- {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b"},
- {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284"},
- {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594"},
- {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e"},
- {file = "pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b"},
- {file = "pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe"},
- {file = "pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f"},
- {file = "pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7"},
- {file = "pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c"},
- {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5"},
- {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c"},
- {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294"},
- {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1"},
- {file = "pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d"},
- {file = "pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815"},
- {file = "pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3"},
- {file = "pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9"},
- {file = "pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586"},
- {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d"},
- {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740"},
- {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e"},
- {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858"},
- {file = "pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36"},
- {file = "pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11"},
- {file = "pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd"},
- {file = "pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a"},
- {file = "pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375"},
- {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553"},
- {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90"},
- {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07"},
- {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb"},
- {file = "pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23"},
- {file = "pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf"},
- {file = "pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c"},
- {file = "pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008"},
- {file = "pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf"},
- {file = "pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3"},
- {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425"},
- {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504"},
- {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5"},
- {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3"},
- {file = "pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460"},
- {file = "pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b"},
- {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034"},
- {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c"},
- {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2"},
- {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad"},
- {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd"},
- {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc"},
- {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56"},
- {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963"},
- {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f"},
- {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51"},
- {file = "pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.14.1"
-
-[[package]]
-name = "pydantic-settings"
-version = "2.12.0"
-description = "Settings management using Pydantic"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev"]
-files = [
- {file = "pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809"},
- {file = "pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0"},
-]
-
-[package.dependencies]
-pydantic = ">=2.7.0"
-python-dotenv = ">=0.21.0"
-typing-inspection = ">=0.4.0"
-
-[package.extras]
-aws-secrets-manager = ["boto3 (>=1.35.0)", "boto3-stubs[secretsmanager]"]
-azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0)"]
-gcp-secret-manager = ["google-cloud-secret-manager (>=2.23.1)"]
-toml = ["tomli (>=2.0.1)"]
-yaml = ["pyyaml (>=6.0.1)"]
-
-[[package]]
-name = "pydeck"
-version = "0.9.1"
-description = "Widget for deck.gl maps"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev", "eval"]
-files = [
- {file = "pydeck-0.9.1-py2.py3-none-any.whl", hash = "sha256:b3f75ba0d273fc917094fa61224f3f6076ca8752b93d46faf3bcfd9f9d59b038"},
- {file = "pydeck-0.9.1.tar.gz", hash = "sha256:f74475ae637951d63f2ee58326757f8d4f9cd9f2a457cf42950715003e2cb605"},
-]
-
-[package.dependencies]
-jinja2 = ">=2.10.1"
-numpy = ">=1.16.4"
-
-[package.extras]
-carto = ["pydeck-carto"]
-jupyter = ["ipykernel (>=5.1.2) ; python_version >= \"3.4\"", "ipython (>=5.8.0) ; python_version < \"3.4\"", "ipywidgets (>=7,<8)", "traitlets (>=4.3.2)"]
-
-[[package]]
-name = "pyfiglet"
-version = "1.0.4"
-description = "Pure-python FIGlet implementation"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "pyfiglet-1.0.4-py3-none-any.whl", hash = "sha256:65b57b7a8e1dff8a67dc8e940a117238661d5e14c3e49121032bd404d9b2b39f"},
- {file = "pyfiglet-1.0.4.tar.gz", hash = "sha256:db9c9940ed1bf3048deff534ed52ff2dafbbc2cd7610b17bb5eca1df6d4278ef"},
-]
-
-[[package]]
-name = "pygments"
-version = "2.19.2"
-description = "Pygments is a syntax highlighting package written in Python."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
- {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
-]
-
-[package.extras]
-windows-terminal = ["colorama (>=0.4.6)"]
-
-[[package]]
-name = "pyparsing"
-version = "3.2.5"
-description = "pyparsing - Classes and methods to define and execute parsing grammars"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e"},
- {file = "pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6"},
-]
-
-[package.extras]
-diagrams = ["jinja2", "railroad-diagrams"]
-
-[[package]]
-name = "pysocks"
-version = "1.7.1"
-description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-groups = ["eval"]
-files = [
- {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"},
- {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"},
- {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"},
-]
-
-[[package]]
-name = "pytest"
-version = "8.4.2"
-description = "pytest: simple powerful testing with Python"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "test"]
-files = [
- {file = "pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79"},
- {file = "pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01"},
-]
-
-[package.dependencies]
-colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
-iniconfig = ">=1"
-packaging = ">=20"
-pluggy = ">=1.5,<2"
-pygments = ">=2.7.2"
-
-[package.extras]
-dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
-
-[[package]]
-name = "pytest-asyncio"
-version = "0.24.0"
-description = "Pytest support for asyncio"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev", "test"]
-files = [
- {file = "pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b"},
- {file = "pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276"},
-]
-
-[package.dependencies]
-pytest = ">=8.2,<9"
-
-[package.extras]
-docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
-testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
-
-[[package]]
-name = "pytest-cov"
-version = "6.3.0"
-description = "Pytest plugin for measuring coverage."
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "pytest_cov-6.3.0-py3-none-any.whl", hash = "sha256:440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749"},
- {file = "pytest_cov-6.3.0.tar.gz", hash = "sha256:35c580e7800f87ce892e687461166e1ac2bcb8fb9e13aea79032518d6e503ff2"},
-]
-
-[package.dependencies]
-coverage = {version = ">=7.5", extras = ["toml"]}
-pluggy = ">=1.2"
-pytest = ">=6.2.5"
-
-[package.extras]
-testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"]
-
-[[package]]
-name = "pytest-mock"
-version = "3.15.1"
-description = "Thin-wrapper around the mock package for easier use with pytest"
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d"},
- {file = "pytest_mock-3.15.1.tar.gz", hash = "sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f"},
-]
-
-[package.dependencies]
-pytest = ">=6.2.5"
-
-[package.extras]
-dev = ["pre-commit", "pytest-asyncio", "tox"]
-
-[[package]]
-name = "pytest-repeat"
-version = "0.9.4"
-description = "pytest plugin for repeating tests"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "pytest_repeat-0.9.4-py3-none-any.whl", hash = "sha256:c1738b4e412a6f3b3b9e0b8b29fcd7a423e50f87381ad9307ef6f5a8601139f3"},
- {file = "pytest_repeat-0.9.4.tar.gz", hash = "sha256:d92ac14dfaa6ffcfe6917e5d16f0c9bc82380c135b03c2a5f412d2637f224485"},
-]
-
-[package.dependencies]
-pytest = "*"
-
-[[package]]
-name = "pytest-rerunfailures"
-version = "16.1"
-description = "pytest plugin to re-run tests to eliminate flaky failures"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev"]
-files = [
- {file = "pytest_rerunfailures-16.1-py3-none-any.whl", hash = "sha256:5d11b12c0ca9a1665b5054052fcc1084f8deadd9328962745ef6b04e26382e86"},
- {file = "pytest_rerunfailures-16.1.tar.gz", hash = "sha256:c38b266db8a808953ebd71ac25c381cb1981a78ff9340a14bcb9f1b9bff1899e"},
-]
-
-[package.dependencies]
-packaging = ">=17.1"
-pytest = ">=7.4,<8.2.2 || >8.2.2"
-
-[[package]]
-name = "pytest-xdist"
-version = "3.8.0"
-description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"},
- {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"},
-]
-
-[package.dependencies]
-execnet = ">=2.1"
-pytest = ">=7.0.0"
-
-[package.extras]
-psutil = ["psutil (>=3.0)"]
-setproctitle = ["setproctitle"]
-testing = ["filelock"]
-
-[[package]]
-name = "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", "dev", "eval"]
-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.2.2"
-description = "Read key-value pairs from a .env file and set them as environment variables"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev"]
-files = [
- {file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"},
- {file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"},
-]
-
-[package.extras]
-cli = ["click (>=5.0)"]
-
-[[package]]
-name = "python-engineio"
-version = "4.12.3"
-description = "Engine.IO server and client for Python"
-optional = false
-python-versions = ">=3.6"
-groups = ["test"]
-files = [
- {file = "python_engineio-4.12.3-py3-none-any.whl", hash = "sha256:7c099abb2a27ea7ab429c04da86ab2d82698cdd6c52406cb73766fe454feb7e1"},
- {file = "python_engineio-4.12.3.tar.gz", hash = "sha256:35633e55ec30915e7fc8f7e34ca8d73ee0c080cec8a8cd04faf2d7396f0a7a7a"},
-]
-
-[package.dependencies]
-simple-websocket = ">=0.10.0"
-
-[package.extras]
-asyncio-client = ["aiohttp (>=3.4)"]
-client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
-docs = ["sphinx"]
-
-[[package]]
-name = "python-socketio"
-version = "5.14.3"
-description = "Socket.IO server and client for Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["test"]
-files = [
- {file = "python_socketio-5.14.3-py3-none-any.whl", hash = "sha256:a5208c1bbf45a8d6328d01ed67e3fa52ec8b186fd3ea44cfcfcbd120f0c71fbe"},
- {file = "python_socketio-5.14.3.tar.gz", hash = "sha256:cd8da5e0666e741b4be19e07882e880f57a4751d1645f92c2bc746c95f23b1eb"},
-]
-
-[package.dependencies]
-bidict = ">=0.21.0"
-python-engineio = ">=4.11.0"
-requests = {version = ">=2.21.0", optional = true, markers = "extra == \"client\""}
-websocket-client = {version = ">=0.54.0", optional = true, markers = "extra == \"client\""}
-
-[package.extras]
-asyncio-client = ["aiohttp (>=3.4)"]
-client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
-dev = ["tox"]
-docs = ["sphinx"]
-
-[[package]]
-name = "pytz"
-version = "2025.2"
-description = "World timezone definitions, modern and historical"
-optional = false
-python-versions = "*"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"},
- {file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"},
-]
-
-[[package]]
-name = "pywin32"
-version = "311"
-description = "Python for Window Extensions"
-optional = false
-python-versions = "*"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "pywin32-311-cp310-cp310-win32.whl", hash = "sha256:d03ff496d2a0cd4a5893504789d4a15399133fe82517455e78bad62efbb7f0a3"},
- {file = "pywin32-311-cp310-cp310-win_amd64.whl", hash = "sha256:797c2772017851984b97180b0bebe4b620bb86328e8a884bb626156295a63b3b"},
- {file = "pywin32-311-cp310-cp310-win_arm64.whl", hash = "sha256:0502d1facf1fed4839a9a51ccbcc63d952cf318f78ffc00a7e78528ac27d7a2b"},
- {file = "pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151"},
- {file = "pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503"},
- {file = "pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2"},
- {file = "pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31"},
- {file = "pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067"},
- {file = "pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852"},
- {file = "pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d"},
- {file = "pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d"},
- {file = "pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a"},
- {file = "pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee"},
- {file = "pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87"},
- {file = "pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42"},
- {file = "pywin32-311-cp38-cp38-win32.whl", hash = "sha256:6c6f2969607b5023b0d9ce2541f8d2cbb01c4f46bc87456017cf63b73f1e2d8c"},
- {file = "pywin32-311-cp38-cp38-win_amd64.whl", hash = "sha256:c8015b09fb9a5e188f83b7b04de91ddca4658cee2ae6f3bc483f0b21a77ef6cd"},
- {file = "pywin32-311-cp39-cp39-win32.whl", hash = "sha256:aba8f82d551a942cb20d4a83413ccbac30790b50efb89a75e4f586ac0bb8056b"},
- {file = "pywin32-311-cp39-cp39-win_amd64.whl", hash = "sha256:e0c4cfb0621281fe40387df582097fd796e80430597cb9944f0ae70447bacd91"},
- {file = "pywin32-311-cp39-cp39-win_arm64.whl", hash = "sha256:62ea666235135fee79bb154e695f3ff67370afefd71bd7fea7512fc70ef31e3d"},
-]
-markers = {main = "platform_system == \"Windows\"", dev = "platform_system == \"Windows\"", eval = "sys_platform == \"win32\"", test = "sys_platform == \"win32\""}
-
-[[package]]
-name = "pyyaml"
-version = "6.0.3"
-description = "YAML parser and emitter for Python"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "PyYAML-6.0.3-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f"},
- {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4"},
- {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3"},
- {file = "PyYAML-6.0.3-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6"},
- {file = "PyYAML-6.0.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369"},
- {file = "PyYAML-6.0.3-cp38-cp38-win32.whl", hash = "sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295"},
- {file = "PyYAML-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b"},
- {file = "pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b"},
- {file = "pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956"},
- {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8"},
- {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198"},
- {file = "pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b"},
- {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0"},
- {file = "pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69"},
- {file = "pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e"},
- {file = "pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c"},
- {file = "pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e"},
- {file = "pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824"},
- {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c"},
- {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00"},
- {file = "pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d"},
- {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a"},
- {file = "pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4"},
- {file = "pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b"},
- {file = "pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf"},
- {file = "pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196"},
- {file = "pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0"},
- {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28"},
- {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c"},
- {file = "pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc"},
- {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e"},
- {file = "pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea"},
- {file = "pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5"},
- {file = "pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b"},
- {file = "pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd"},
- {file = "pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8"},
- {file = "pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1"},
- {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c"},
- {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5"},
- {file = "pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6"},
- {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6"},
- {file = "pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be"},
- {file = "pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26"},
- {file = "pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c"},
- {file = "pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb"},
- {file = "pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac"},
- {file = "pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310"},
- {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7"},
- {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788"},
- {file = "pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5"},
- {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764"},
- {file = "pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35"},
- {file = "pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac"},
- {file = "pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3"},
- {file = "pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3"},
- {file = "pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba"},
- {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c"},
- {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702"},
- {file = "pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c"},
- {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065"},
- {file = "pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65"},
- {file = "pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9"},
- {file = "pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b"},
- {file = "pyyaml-6.0.3-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da"},
- {file = "pyyaml-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917"},
- {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9"},
- {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5"},
- {file = "pyyaml-6.0.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a"},
- {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926"},
- {file = "pyyaml-6.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7"},
- {file = "pyyaml-6.0.3-cp39-cp39-win32.whl", hash = "sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0"},
- {file = "pyyaml-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007"},
- {file = "pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f"},
-]
-
-[[package]]
-name = "pyzmq"
-version = "27.1.0"
-description = "Python bindings for 0MQ"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval", "test"]
-files = [
- {file = "pyzmq-27.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4"},
- {file = "pyzmq-27.1.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556"},
- {file = "pyzmq-27.1.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b"},
- {file = "pyzmq-27.1.0-cp310-cp310-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e"},
- {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526"},
- {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1"},
- {file = "pyzmq-27.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386"},
- {file = "pyzmq-27.1.0-cp310-cp310-win32.whl", hash = "sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda"},
- {file = "pyzmq-27.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f"},
- {file = "pyzmq-27.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32"},
- {file = "pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86"},
- {file = "pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581"},
- {file = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f"},
- {file = "pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e"},
- {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e"},
- {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2"},
- {file = "pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394"},
- {file = "pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f"},
- {file = "pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97"},
- {file = "pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07"},
- {file = "pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc"},
- {file = "pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113"},
- {file = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233"},
- {file = "pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31"},
- {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28"},
- {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856"},
- {file = "pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496"},
- {file = "pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd"},
- {file = "pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf"},
- {file = "pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f"},
- {file = "pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5"},
- {file = "pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6"},
- {file = "pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7"},
- {file = "pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05"},
- {file = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9"},
- {file = "pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128"},
- {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39"},
- {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97"},
- {file = "pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db"},
- {file = "pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c"},
- {file = "pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2"},
- {file = "pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e"},
- {file = "pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a"},
- {file = "pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea"},
- {file = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96"},
- {file = "pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d"},
- {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146"},
- {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd"},
- {file = "pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a"},
- {file = "pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92"},
- {file = "pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0"},
- {file = "pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7"},
- {file = "pyzmq-27.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:18339186c0ed0ce5835f2656cdfb32203125917711af64da64dbaa3d949e5a1b"},
- {file = "pyzmq-27.1.0-cp38-cp38-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:753d56fba8f70962cd8295fb3edb40b9b16deaa882dd2b5a3a2039f9ff7625aa"},
- {file = "pyzmq-27.1.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b721c05d932e5ad9ff9344f708c96b9e1a485418c6618d765fca95d4daacfbef"},
- {file = "pyzmq-27.1.0-cp38-cp38-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7be883ff3d722e6085ee3f4afc057a50f7f2e0c72d289fd54df5706b4e3d3a50"},
- {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b2e592db3a93128daf567de9650a2f3859017b3f7a66bc4ed6e4779d6034976f"},
- {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ad68808a61cbfbbae7ba26d6233f2a4aa3b221de379ce9ee468aa7a83b9c36b0"},
- {file = "pyzmq-27.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e2687c2d230e8d8584fbea433c24382edfeda0c60627aca3446aa5e58d5d1831"},
- {file = "pyzmq-27.1.0-cp38-cp38-win32.whl", hash = "sha256:a1aa0ee920fb3825d6c825ae3f6c508403b905b698b6460408ebd5bb04bbb312"},
- {file = "pyzmq-27.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:df7cd397ece96cf20a76fae705d40efbab217d217897a5053267cd88a700c266"},
- {file = "pyzmq-27.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:96c71c32fff75957db6ae33cd961439f386505c6e6b377370af9b24a1ef9eafb"},
- {file = "pyzmq-27.1.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:49d3980544447f6bd2968b6ac913ab963a49dcaa2d4a2990041f16057b04c429"},
- {file = "pyzmq-27.1.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:849ca054d81aa1c175c49484afaaa5db0622092b5eccb2055f9f3bb8f703782d"},
- {file = "pyzmq-27.1.0-cp39-cp39-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3970778e74cb7f85934d2b926b9900e92bfe597e62267d7499acc39c9c28e345"},
- {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:da96ecdcf7d3919c3be2de91a8c513c186f6762aa6cf7c01087ed74fad7f0968"},
- {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9541c444cfe1b1c0156c5c86ece2bb926c7079a18e7b47b0b1b3b1b875e5d098"},
- {file = "pyzmq-27.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e30a74a39b93e2e1591b58eb1acef4902be27c957a8720b0e368f579b82dc22f"},
- {file = "pyzmq-27.1.0-cp39-cp39-win32.whl", hash = "sha256:b1267823d72d1e40701dcba7edc45fd17f71be1285557b7fe668887150a14b78"},
- {file = "pyzmq-27.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c996ded912812a2fcd7ab6574f4ad3edc27cb6510349431e4930d4196ade7db"},
- {file = "pyzmq-27.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:346e9ba4198177a07e7706050f35d733e08c1c1f8ceacd5eb6389d653579ffbc"},
- {file = "pyzmq-27.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6"},
- {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90"},
- {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62"},
- {file = "pyzmq-27.1.0-pp310-pypy310_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74"},
- {file = "pyzmq-27.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba"},
- {file = "pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066"},
- {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604"},
- {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c"},
- {file = "pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271"},
- {file = "pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355"},
- {file = "pyzmq-27.1.0-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:50081a4e98472ba9f5a02850014b4c9b629da6710f8f14f3b15897c666a28f1b"},
- {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:510869f9df36ab97f89f4cff9d002a89ac554c7ac9cadd87d444aa4cf66abd27"},
- {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f8426a01b1c4098a750973c37131cf585f61c7911d735f729935a0c701b68d3"},
- {file = "pyzmq-27.1.0-pp38-pypy38_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:726b6a502f2e34c6d2ada5e702929586d3ac948a4dbbb7fed9854ec8c0466027"},
- {file = "pyzmq-27.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:bd67e7c8f4654bef471c0b1ca6614af0b5202a790723a58b79d9584dc8022a78"},
- {file = "pyzmq-27.1.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:722ea791aa233ac0a819fc2c475e1292c76930b31f1d828cb61073e2fe5e208f"},
- {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:01f9437501886d3a1dd4b02ef59fb8cc384fa718ce066d52f175ee49dd5b7ed8"},
- {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4a19387a3dddcc762bfd2f570d14e2395b2c9701329b266f83dd87a2b3cbd381"},
- {file = "pyzmq-27.1.0-pp39-pypy39_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c618fbcd069e3a29dcd221739cacde52edcc681f041907867e0f5cc7e85f172"},
- {file = "pyzmq-27.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff8d114d14ac671d88c89b9224c63d6c4e5a613fe8acd5594ce53d752a3aafe9"},
- {file = "pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540"},
-]
-
-[package.dependencies]
-cffi = {version = "*", markers = "implementation_name == \"pypy\""}
-
-[[package]]
-name = "qdrant-client"
-version = "1.15.0"
-description = "Client library for the Qdrant vector search engine"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "qdrant_client-1.15.0-py3-none-any.whl", hash = "sha256:f18bb311543de7e256ffa831be0d8a9d0729aaf549db7bcf95a5d356b48143f2"},
- {file = "qdrant_client-1.15.0.tar.gz", hash = "sha256:475433b0acec51b66a132e91b631abe922accc64744bbb3180a04fe1fe889843"},
-]
-
-[package.dependencies]
-grpcio = ">=1.41.0"
-httpx = {version = ">=0.20.0", extras = ["http2"]}
-numpy = {version = ">=1.26", markers = "python_version == \"3.12\""}
-portalocker = ">=2.7.0,<4.0"
-protobuf = ">=3.20.0"
-pydantic = ">=1.10.8,<2.0.dev0 || >2.2.0"
-urllib3 = ">=1.26.14,<3"
-
-[package.extras]
-fastembed = ["fastembed (>=0.7,<0.8)"]
-fastembed-gpu = ["fastembed-gpu (>=0.7,<0.8)"]
-
-[[package]]
-name = "qdrant-haystack"
-version = "7.0.0"
-description = "An integration of Qdrant ANN vector database backend with Haystack"
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "qdrant_haystack-7.0.0-py3-none-any.whl", hash = "sha256:322a4bfb5f119a7739315fa2331c25b6835ce5fe89b8d72cabe69f8ab2bb3222"},
- {file = "qdrant_haystack-7.0.0.tar.gz", hash = "sha256:439efd2d536e211a477d57a293d53d2f0b02df20d595a5585ba463ecc3067e1f"},
-]
-
-[package.dependencies]
-haystack-ai = "*"
-qdrant-client = ">=1.10.0"
-
-[[package]]
-name = "referencing"
-version = "0.37.0"
-description = "JSON Referencing + Python"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231"},
- {file = "referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8"},
-]
-
-[package.dependencies]
-attrs = ">=22.2.0"
-rpds-py = ">=0.7.0"
-typing-extensions = {version = ">=4.4.0", markers = "python_version < \"3.13\""}
-
-[[package]]
-name = "regex"
-version = "2025.11.3"
-description = "Alternative regular expression module, to replace re."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "regex-2025.11.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2b441a4ae2c8049106e8b39973bfbddfb25a179dda2bdb99b0eeb60c40a6a3af"},
- {file = "regex-2025.11.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2fa2eed3f76677777345d2f81ee89f5de2f5745910e805f7af7386a920fa7313"},
- {file = "regex-2025.11.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8b4a27eebd684319bdf473d39f1d79eed36bf2cd34bd4465cdb4618d82b3d56"},
- {file = "regex-2025.11.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cf77eac15bd264986c4a2c63353212c095b40f3affb2bc6b4ef80c4776c1a28"},
- {file = "regex-2025.11.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f9ee819f94c6abfa56ec7b1dbab586f41ebbdc0a57e6524bd5e7f487a878c7"},
- {file = "regex-2025.11.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:838441333bc90b829406d4a03cb4b8bf7656231b84358628b0406d803931ef32"},
- {file = "regex-2025.11.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfe6d3f0c9e3b7e8c0c694b24d25e677776f5ca26dce46fd6b0489f9c8339391"},
- {file = "regex-2025.11.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2ab815eb8a96379a27c3b6157fcb127c8f59c36f043c1678110cea492868f1d5"},
- {file = "regex-2025.11.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:728a9d2d173a65b62bdc380b7932dd8e74ed4295279a8fe1021204ce210803e7"},
- {file = "regex-2025.11.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:509dc827f89c15c66a0c216331260d777dd6c81e9a4e4f830e662b0bb296c313"},
- {file = "regex-2025.11.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:849202cd789e5f3cf5dcc7822c34b502181b4824a65ff20ce82da5524e45e8e9"},
- {file = "regex-2025.11.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b6f78f98741dcc89607c16b1e9426ee46ce4bf31ac5e6b0d40e81c89f3481ea5"},
- {file = "regex-2025.11.3-cp310-cp310-win32.whl", hash = "sha256:149eb0bba95231fb4f6d37c8f760ec9fa6fabf65bab555e128dde5f2475193ec"},
- {file = "regex-2025.11.3-cp310-cp310-win_amd64.whl", hash = "sha256:ee3a83ce492074c35a74cc76cf8235d49e77b757193a5365ff86e3f2f93db9fd"},
- {file = "regex-2025.11.3-cp310-cp310-win_arm64.whl", hash = "sha256:38af559ad934a7b35147716655d4a2f79fcef2d695ddfe06a06ba40ae631fa7e"},
- {file = "regex-2025.11.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eadade04221641516fa25139273505a1c19f9bf97589a05bc4cfcd8b4a618031"},
- {file = "regex-2025.11.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:feff9e54ec0dd3833d659257f5c3f5322a12eee58ffa360984b716f8b92983f4"},
- {file = "regex-2025.11.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3b30bc921d50365775c09a7ed446359e5c0179e9e2512beec4a60cbcef6ddd50"},
- {file = "regex-2025.11.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f99be08cfead2020c7ca6e396c13543baea32343b7a9a5780c462e323bd8872f"},
- {file = "regex-2025.11.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6dd329a1b61c0ee95ba95385fb0c07ea0d3fe1a21e1349fa2bec272636217118"},
- {file = "regex-2025.11.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4c5238d32f3c5269d9e87be0cf096437b7622b6920f5eac4fd202468aaeb34d2"},
- {file = "regex-2025.11.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10483eefbfb0adb18ee9474498c9a32fcf4e594fbca0543bb94c48bac6183e2e"},
- {file = "regex-2025.11.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:78c2d02bb6e1da0720eedc0bad578049cad3f71050ef8cd065ecc87691bed2b0"},
- {file = "regex-2025.11.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e6b49cd2aad93a1790ce9cffb18964f6d3a4b0b3dbdbd5de094b65296fce6e58"},
- {file = "regex-2025.11.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:885b26aa3ee56433b630502dc3d36ba78d186a00cc535d3806e6bfd9ed3c70ab"},
- {file = "regex-2025.11.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ddd76a9f58e6a00f8772e72cff8ebcff78e022be95edf018766707c730593e1e"},
- {file = "regex-2025.11.3-cp311-cp311-win32.whl", hash = "sha256:3e816cc9aac1cd3cc9a4ec4d860f06d40f994b5c7b4d03b93345f44e08cc68bf"},
- {file = "regex-2025.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:087511f5c8b7dfbe3a03f5d5ad0c2a33861b1fc387f21f6f60825a44865a385a"},
- {file = "regex-2025.11.3-cp311-cp311-win_arm64.whl", hash = "sha256:1ff0d190c7f68ae7769cd0313fe45820ba07ffebfddfaa89cc1eb70827ba0ddc"},
- {file = "regex-2025.11.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bc8ab71e2e31b16e40868a40a69007bc305e1109bd4658eb6cad007e0bf67c41"},
- {file = "regex-2025.11.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:22b29dda7e1f7062a52359fca6e58e548e28c6686f205e780b02ad8ef710de36"},
- {file = "regex-2025.11.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a91e4a29938bc1a082cc28fdea44be420bf2bebe2665343029723892eb073e1"},
- {file = "regex-2025.11.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08b884f4226602ad40c5d55f52bf91a9df30f513864e0054bad40c0e9cf1afb7"},
- {file = "regex-2025.11.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3e0b11b2b2433d1c39c7c7a30e3f3d0aeeea44c2a8d0bae28f6b95f639927a69"},
- {file = "regex-2025.11.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87eb52a81ef58c7ba4d45c3ca74e12aa4b4e77816f72ca25258a85b3ea96cb48"},
- {file = "regex-2025.11.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a12ab1f5c29b4e93db518f5e3872116b7e9b1646c9f9f426f777b50d44a09e8c"},
- {file = "regex-2025.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7521684c8c7c4f6e88e35ec89680ee1aa8358d3f09d27dfbdf62c446f5d4c695"},
- {file = "regex-2025.11.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7fe6e5440584e94cc4b3f5f4d98a25e29ca12dccf8873679a635638349831b98"},
- {file = "regex-2025.11.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8e026094aa12b43f4fd74576714e987803a315c76edb6b098b9809db5de58f74"},
- {file = "regex-2025.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:435bbad13e57eb5606a68443af62bed3556de2f46deb9f7d4237bc2f1c9fb3a0"},
- {file = "regex-2025.11.3-cp312-cp312-win32.whl", hash = "sha256:3839967cf4dc4b985e1570fd8d91078f0c519f30491c60f9ac42a8db039be204"},
- {file = "regex-2025.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:e721d1b46e25c481dc5ded6f4b3f66c897c58d2e8cfdf77bbced84339108b0b9"},
- {file = "regex-2025.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:64350685ff08b1d3a6fff33f45a9ca183dc1d58bbfe4981604e70ec9801bbc26"},
- {file = "regex-2025.11.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c1e448051717a334891f2b9a620fe36776ebf3dd8ec46a0b877c8ae69575feb4"},
- {file = "regex-2025.11.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9b5aca4d5dfd7fbfbfbdaf44850fcc7709a01146a797536a8f84952e940cca76"},
- {file = "regex-2025.11.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:04d2765516395cf7dda331a244a3282c0f5ae96075f728629287dfa6f76ba70a"},
- {file = "regex-2025.11.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d9903ca42bfeec4cebedba8022a7c97ad2aab22e09573ce9976ba01b65e4361"},
- {file = "regex-2025.11.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:639431bdc89d6429f6721625e8129413980ccd62e9d3f496be618a41d205f160"},
- {file = "regex-2025.11.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f117efad42068f9715677c8523ed2be1518116d1c49b1dd17987716695181efe"},
- {file = "regex-2025.11.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4aecb6f461316adf9f1f0f6a4a1a3d79e045f9b71ec76055a791affa3b285850"},
- {file = "regex-2025.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3b3a5f320136873cc5561098dfab677eea139521cb9a9e8db98b7e64aef44cbc"},
- {file = "regex-2025.11.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:75fa6f0056e7efb1f42a1c34e58be24072cb9e61a601340cc1196ae92326a4f9"},
- {file = "regex-2025.11.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:dbe6095001465294f13f1adcd3311e50dd84e5a71525f20a10bd16689c61ce0b"},
- {file = "regex-2025.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:454d9b4ae7881afbc25015b8627c16d88a597479b9dea82b8c6e7e2e07240dc7"},
- {file = "regex-2025.11.3-cp313-cp313-win32.whl", hash = "sha256:28ba4d69171fc6e9896337d4fc63a43660002b7da53fc15ac992abcf3410917c"},
- {file = "regex-2025.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:bac4200befe50c670c405dc33af26dad5a3b6b255dd6c000d92fe4629f9ed6a5"},
- {file = "regex-2025.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:2292cd5a90dab247f9abe892ac584cb24f0f54680c73fcb4a7493c66c2bf2467"},
- {file = "regex-2025.11.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:1eb1ebf6822b756c723e09f5186473d93236c06c579d2cc0671a722d2ab14281"},
- {file = "regex-2025.11.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1e00ec2970aab10dc5db34af535f21fcf32b4a31d99e34963419636e2f85ae39"},
- {file = "regex-2025.11.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a4cb042b615245d5ff9b3794f56be4138b5adc35a4166014d31d1814744148c7"},
- {file = "regex-2025.11.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44f264d4bf02f3176467d90b294d59bf1db9fe53c141ff772f27a8b456b2a9ed"},
- {file = "regex-2025.11.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7be0277469bf3bd7a34a9c57c1b6a724532a0d235cd0dc4e7f4316f982c28b19"},
- {file = "regex-2025.11.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0d31e08426ff4b5b650f68839f5af51a92a5b51abd8554a60c2fbc7c71f25d0b"},
- {file = "regex-2025.11.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e43586ce5bd28f9f285a6e729466841368c4a0353f6fd08d4ce4630843d3648a"},
- {file = "regex-2025.11.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0f9397d561a4c16829d4e6ff75202c1c08b68a3bdbfe29dbfcdb31c9830907c6"},
- {file = "regex-2025.11.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:dd16e78eb18ffdb25ee33a0682d17912e8cc8a770e885aeee95020046128f1ce"},
- {file = "regex-2025.11.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:ffcca5b9efe948ba0661e9df0fa50d2bc4b097c70b9810212d6b62f05d83b2dd"},
- {file = "regex-2025.11.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c56b4d162ca2b43318ac671c65bd4d563e841a694ac70e1a976ac38fcf4ca1d2"},
- {file = "regex-2025.11.3-cp313-cp313t-win32.whl", hash = "sha256:9ddc42e68114e161e51e272f667d640f97e84a2b9ef14b7477c53aac20c2d59a"},
- {file = "regex-2025.11.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7a7c7fdf755032ffdd72c77e3d8096bdcb0eb92e89e17571a196f03d88b11b3c"},
- {file = "regex-2025.11.3-cp313-cp313t-win_arm64.whl", hash = "sha256:df9eb838c44f570283712e7cff14c16329a9f0fb19ca492d21d4b7528ee6821e"},
- {file = "regex-2025.11.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9697a52e57576c83139d7c6f213d64485d3df5bf84807c35fa409e6c970801c6"},
- {file = "regex-2025.11.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e18bc3f73bd41243c9b38a6d9f2366cd0e0137a9aebe2d8ff76c5b67d4c0a3f4"},
- {file = "regex-2025.11.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:61a08bcb0ec14ff4e0ed2044aad948d0659604f824cbd50b55e30b0ec6f09c73"},
- {file = "regex-2025.11.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9c30003b9347c24bcc210958c5d167b9e4f9be786cb380a7d32f14f9b84674f"},
- {file = "regex-2025.11.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4e1e592789704459900728d88d41a46fe3969b82ab62945560a31732ffc19a6d"},
- {file = "regex-2025.11.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6538241f45eb5a25aa575dbba1069ad786f68a4f2773a29a2bd3dd1f9de787be"},
- {file = "regex-2025.11.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce22519c989bb72a7e6b36a199384c53db7722fe669ba891da75907fe3587db"},
- {file = "regex-2025.11.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:66d559b21d3640203ab9075797a55165d79017520685fb407b9234d72ab63c62"},
- {file = "regex-2025.11.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:669dcfb2e38f9e8c69507bace46f4889e3abbfd9b0c29719202883c0a603598f"},
- {file = "regex-2025.11.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:32f74f35ff0f25a5021373ac61442edcb150731fbaa28286bbc8bb1582c89d02"},
- {file = "regex-2025.11.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e6c7a21dffba883234baefe91bc3388e629779582038f75d2a5be918e250f0ed"},
- {file = "regex-2025.11.3-cp314-cp314-win32.whl", hash = "sha256:795ea137b1d809eb6836b43748b12634291c0ed55ad50a7d72d21edf1cd565c4"},
- {file = "regex-2025.11.3-cp314-cp314-win_amd64.whl", hash = "sha256:9f95fbaa0ee1610ec0fc6b26668e9917a582ba80c52cc6d9ada15e30aa9ab9ad"},
- {file = "regex-2025.11.3-cp314-cp314-win_arm64.whl", hash = "sha256:dfec44d532be4c07088c3de2876130ff0fbeeacaa89a137decbbb5f665855a0f"},
- {file = "regex-2025.11.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ba0d8a5d7f04f73ee7d01d974d47c5834f8a1b0224390e4fe7c12a3a92a78ecc"},
- {file = "regex-2025.11.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:442d86cf1cfe4faabf97db7d901ef58347efd004934da045c745e7b5bd57ac49"},
- {file = "regex-2025.11.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fd0a5e563c756de210bb964789b5abe4f114dacae9104a47e1a649b910361536"},
- {file = "regex-2025.11.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf3490bcbb985a1ae97b2ce9ad1c0f06a852d5b19dde9b07bdf25bf224248c95"},
- {file = "regex-2025.11.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3809988f0a8b8c9dcc0f92478d6501fac7200b9ec56aecf0ec21f4a2ec4b6009"},
- {file = "regex-2025.11.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f4ff94e58e84aedb9c9fce66d4ef9f27a190285b451420f297c9a09f2b9abee9"},
- {file = "regex-2025.11.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eb542fd347ce61e1321b0a6b945d5701528dca0cd9759c2e3bb8bd57e47964d"},
- {file = "regex-2025.11.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d6c2d5919075a1f2e413c00b056ea0c2f065b3f5fe83c3d07d325ab92dce51d6"},
- {file = "regex-2025.11.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3f8bf11a4827cc7ce5a53d4ef6cddd5ad25595d3c1435ef08f76825851343154"},
- {file = "regex-2025.11.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:22c12d837298651e5550ac1d964e4ff57c3f56965fc1812c90c9fb2028eaf267"},
- {file = "regex-2025.11.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:62ba394a3dda9ad41c7c780f60f6e4a70988741415ae96f6d1bf6c239cf01379"},
- {file = "regex-2025.11.3-cp314-cp314t-win32.whl", hash = "sha256:4bf146dca15cdd53224a1bf46d628bd7590e4a07fbb69e720d561aea43a32b38"},
- {file = "regex-2025.11.3-cp314-cp314t-win_amd64.whl", hash = "sha256:adad1a1bcf1c9e76346e091d22d23ac54ef28e1365117d99521631078dfec9de"},
- {file = "regex-2025.11.3-cp314-cp314t-win_arm64.whl", hash = "sha256:c54f768482cef41e219720013cd05933b6f971d9562544d691c68699bf2b6801"},
- {file = "regex-2025.11.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:81519e25707fc076978c6143b81ea3dc853f176895af05bf7ec51effe818aeec"},
- {file = "regex-2025.11.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3bf28b1873a8af8bbb58c26cc56ea6e534d80053b41fb511a35795b6de507e6a"},
- {file = "regex-2025.11.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:856a25c73b697f2ce2a24e7968285579e62577a048526161a2c0f53090bea9f9"},
- {file = "regex-2025.11.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a3d571bd95fade53c86c0517f859477ff3a93c3fde10c9e669086f038e0f207"},
- {file = "regex-2025.11.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:732aea6de26051af97b94bc98ed86448821f839d058e5d259c72bf6d73ad0fc0"},
- {file = "regex-2025.11.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:51c1c1847128238f54930edb8805b660305dca164645a9fd29243f5610beea34"},
- {file = "regex-2025.11.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22dd622a402aad4558277305350699b2be14bc59f64d64ae1d928ce7d072dced"},
- {file = "regex-2025.11.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f3b5a391c7597ffa96b41bd5cbd2ed0305f515fcbb367dfa72735679d5502364"},
- {file = "regex-2025.11.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:cc4076a5b4f36d849fd709284b4a3b112326652f3b0466f04002a6c15a0c96c1"},
- {file = "regex-2025.11.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:a295ca2bba5c1c885826ce3125fa0b9f702a1be547d821c01d65f199e10c01e2"},
- {file = "regex-2025.11.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:b4774ff32f18e0504bfc4e59a3e71e18d83bc1e171a3c8ed75013958a03b2f14"},
- {file = "regex-2025.11.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22e7d1cdfa88ef33a2ae6aa0d707f9255eb286ffbd90045f1088246833223aee"},
- {file = "regex-2025.11.3-cp39-cp39-win32.whl", hash = "sha256:74d04244852ff73b32eeede4f76f51c5bcf44bc3c207bc3e6cf1c5c45b890708"},
- {file = "regex-2025.11.3-cp39-cp39-win_amd64.whl", hash = "sha256:7a50cd39f73faa34ec18d6720ee25ef10c4c1839514186fcda658a06c06057a2"},
- {file = "regex-2025.11.3-cp39-cp39-win_arm64.whl", hash = "sha256:43b4fb020e779ca81c1b5255015fe2b82816c76ec982354534ad9ec09ad7c9e3"},
- {file = "regex-2025.11.3.tar.gz", hash = "sha256:1fedc720f9bb2494ce31a58a1631f9c82df6a09b49c19517ea5cc280b4541e01"},
-]
-
-[[package]]
-name = "requests"
-version = "2.32.5"
-description = "Python HTTP for Humans."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"},
- {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"},
-]
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset_normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-PySocks = {version = ">=1.5.6,<1.5.7 || >1.5.7", optional = true, markers = "extra == \"socks\""}
-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 = "rich"
-version = "14.2.0"
-description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
-optional = false
-python-versions = ">=3.8.0"
-groups = ["main", "dev"]
-files = [
- {file = "rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd"},
- {file = "rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4"},
-]
-
-[package.dependencies]
-markdown-it-py = ">=2.2.0"
-pygments = ">=2.13.0,<3.0.0"
-
-[package.extras]
-jupyter = ["ipywidgets (>=7.5.1,<9)"]
-
-[[package]]
-name = "rpds-py"
-version = "0.28.0"
-description = "Python bindings to Rust's persistent data structures (rpds)"
-optional = false
-python-versions = ">=3.10"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "rpds_py-0.28.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:7b6013db815417eeb56b2d9d7324e64fcd4fa289caeee6e7a78b2e11fc9b438a"},
- {file = "rpds_py-0.28.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a4c6b05c685c0c03f80dabaeb73e74218c49deea965ca63f76a752807397207"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4794c6c3fbe8f9ac87699b131a1f26e7b4abcf6d828da46a3a52648c7930eba"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2e8456b6ee5527112ff2354dd9087b030e3429e43a74f480d4a5ca79d269fd85"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:beb880a9ca0a117415f241f66d56025c02037f7c4efc6fe59b5b8454f1eaa50d"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6897bebb118c44b38c9cb62a178e09f1593c949391b9a1a6fe777ccab5934ee7"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b553dd06e875249fd43efd727785efb57a53180e0fde321468222eabbeaafa"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:f0b2044fdddeea5b05df832e50d2a06fe61023acb44d76978e1b060206a8a476"},
- {file = "rpds_py-0.28.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05cf1e74900e8da73fa08cc76c74a03345e5a3e37691d07cfe2092d7d8e27b04"},
- {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:efd489fec7c311dae25e94fe7eeda4b3d06be71c68f2cf2e8ef990ffcd2cd7e8"},
- {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ada7754a10faacd4f26067e62de52d6af93b6d9542f0df73c57b9771eb3ba9c4"},
- {file = "rpds_py-0.28.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c2a34fd26588949e1e7977cfcbb17a9a42c948c100cab890c6d8d823f0586457"},
- {file = "rpds_py-0.28.0-cp310-cp310-win32.whl", hash = "sha256:f9174471d6920cbc5e82a7822de8dfd4dcea86eb828b04fc8c6519a77b0ee51e"},
- {file = "rpds_py-0.28.0-cp310-cp310-win_amd64.whl", hash = "sha256:6e32dd207e2c4f8475257a3540ab8a93eff997abfa0a3fdb287cae0d6cd874b8"},
- {file = "rpds_py-0.28.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:03065002fd2e287725d95fbc69688e0c6daf6c6314ba38bdbaa3895418e09296"},
- {file = "rpds_py-0.28.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28ea02215f262b6d078daec0b45344c89e161eab9526b0d898221d96fdda5f27"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dbade8fbf30bcc551cb352376c0ad64b067e4fc56f90e22ba70c3ce205988c"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c03002f54cc855860bfdc3442928ffdca9081e73b5b382ed0b9e8efe6e5e205"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b9699fa7990368b22032baf2b2dce1f634388e4ffc03dfefaaac79f4695edc95"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9b06fe1a75e05e0713f06ea0c89ecb6452210fd60e2f1b6ddc1067b990e08d9"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9f83e7b326a3f9ec3ef84cda98fb0a74c7159f33e692032233046e7fd15da2"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:0d3259ea9ad8743a75a43eb7819324cdab393263c91be86e2d1901ee65c314e0"},
- {file = "rpds_py-0.28.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a7548b345f66f6695943b4ef6afe33ccd3f1b638bd9afd0f730dd255c249c9e"},
- {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c9a40040aa388b037eb39416710fbcce9443498d2eaab0b9b45ae988b53f5c67"},
- {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f60c7ea34e78c199acd0d3cda37a99be2c861dd2b8cf67399784f70c9f8e57d"},
- {file = "rpds_py-0.28.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1571ae4292649100d743b26d5f9c63503bb1fedf538a8f29a98dce2d5ba6b4e6"},
- {file = "rpds_py-0.28.0-cp311-cp311-win32.whl", hash = "sha256:5cfa9af45e7c1140af7321fa0bef25b386ee9faa8928c80dc3a5360971a29e8c"},
- {file = "rpds_py-0.28.0-cp311-cp311-win_amd64.whl", hash = "sha256:dd8d86b5d29d1b74100982424ba53e56033dc47720a6de9ba0259cf81d7cecaa"},
- {file = "rpds_py-0.28.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e27d3a5709cc2b3e013bf93679a849213c79ae0573f9b894b284b55e729e120"},
- {file = "rpds_py-0.28.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6b4f28583a4f247ff60cd7bdda83db8c3f5b05a7a82ff20dd4b078571747708f"},
- {file = "rpds_py-0.28.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d678e91b610c29c4b3d52a2c148b641df2b4676ffe47c59f6388d58b99cdc424"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e819e0e37a44a78e1383bf1970076e2ccc4dc8c2bbaa2f9bd1dc987e9afff628"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5ee514e0f0523db5d3fb171f397c54875dbbd69760a414dccf9d4d7ad628b5bd"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3fa06d27fdcee47f07a39e02862da0100cb4982508f5ead53ec533cd5fe55e"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:46959ef2e64f9e4a41fc89aa20dbca2b85531f9a72c21099a3360f35d10b0d5a"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8455933b4bcd6e83fde3fefc987a023389c4b13f9a58c8d23e4b3f6d13f78c84"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ad50614a02c8c2962feebe6012b52f9802deec4263946cddea37aaf28dd25a66"},
- {file = "rpds_py-0.28.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5deca01b271492553fdb6c7fd974659dce736a15bae5dad7ab8b93555bceb28"},
- {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:735f8495a13159ce6a0d533f01e8674cec0c57038c920495f87dcb20b3ddb48a"},
- {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:961ca621ff10d198bbe6ba4957decca61aa2a0c56695384c1d6b79bf61436df5"},
- {file = "rpds_py-0.28.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2374e16cc9131022e7d9a8f8d65d261d9ba55048c78f3b6e017971a4f5e6353c"},
- {file = "rpds_py-0.28.0-cp312-cp312-win32.whl", hash = "sha256:d15431e334fba488b081d47f30f091e5d03c18527c325386091f31718952fe08"},
- {file = "rpds_py-0.28.0-cp312-cp312-win_amd64.whl", hash = "sha256:a410542d61fc54710f750d3764380b53bf09e8c4edbf2f9141a82aa774a04f7c"},
- {file = "rpds_py-0.28.0-cp312-cp312-win_arm64.whl", hash = "sha256:1f0cfd1c69e2d14f8c892b893997fa9a60d890a0c8a603e88dca4955f26d1edd"},
- {file = "rpds_py-0.28.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e9e184408a0297086f880556b6168fa927d677716f83d3472ea333b42171ee3b"},
- {file = "rpds_py-0.28.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:edd267266a9b0448f33dc465a97cfc5d467594b600fe28e7fa2f36450e03053a"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85beb8b3f45e4e32f6802fb6cd6b17f615ef6c6a52f265371fb916fae02814aa"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d2412be8d00a1b895f8ad827cc2116455196e20ed994bb704bf138fe91a42724"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf128350d384b777da0e68796afdcebc2e9f63f0e9f242217754e647f6d32491"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a2036d09b363aa36695d1cc1a97b36865597f4478470b0697b5ee9403f4fe399"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8e1e9be4fa6305a16be628959188e4fd5cd6f1b0e724d63c6d8b2a8adf74ea6"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0a403460c9dd91a7f23fc3188de6d8977f1d9603a351d5db6cf20aaea95b538d"},
- {file = "rpds_py-0.28.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d7366b6553cdc805abcc512b849a519167db8f5e5c3472010cd1228b224265cb"},
- {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b43c6a3726efd50f18d8120ec0551241c38785b68952d240c45ea553912ac41"},
- {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0cb7203c7bc69d7c1585ebb33a2e6074492d2fc21ad28a7b9d40457ac2a51ab7"},
- {file = "rpds_py-0.28.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a52a5169c664dfb495882adc75c304ae1d50df552fbd68e100fdc719dee4ff9"},
- {file = "rpds_py-0.28.0-cp313-cp313-win32.whl", hash = "sha256:2e42456917b6687215b3e606ab46aa6bca040c77af7df9a08a6dcfe8a4d10ca5"},
- {file = "rpds_py-0.28.0-cp313-cp313-win_amd64.whl", hash = "sha256:e0a0311caedc8069d68fc2bf4c9019b58a2d5ce3cd7cb656c845f1615b577e1e"},
- {file = "rpds_py-0.28.0-cp313-cp313-win_arm64.whl", hash = "sha256:04c1b207ab8b581108801528d59ad80aa83bb170b35b0ddffb29c20e411acdc1"},
- {file = "rpds_py-0.28.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f296ea3054e11fc58ad42e850e8b75c62d9a93a9f981ad04b2e5ae7d2186ff9c"},
- {file = "rpds_py-0.28.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5a7306c19b19005ad98468fcefeb7100b19c79fc23a5f24a12e06d91181193fa"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5d9b86aa501fed9862a443c5c3116f6ead8bc9296185f369277c42542bd646b"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e5bbc701eff140ba0e872691d573b3d5d30059ea26e5785acba9132d10c8c31d"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5690671cd672a45aa8616d7374fdf334a1b9c04a0cac3c854b1136e92374fe"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9f1d92ecea4fa12f978a367c32a5375a1982834649cdb96539dcdc12e609ab1a"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d252db6b1a78d0a3928b6190156042d54c93660ce4d98290d7b16b5296fb7cc"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d61b355c3275acb825f8777d6c4505f42b5007e357af500939d4a35b19177259"},
- {file = "rpds_py-0.28.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:acbe5e8b1026c0c580d0321c8aae4b0a1e1676861d48d6e8c6586625055b606a"},
- {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8aa23b6f0fc59b85b4c7d89ba2965af274346f738e8d9fc2455763602e62fd5f"},
- {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7b14b0c680286958817c22d76fcbca4800ddacef6f678f3a7c79a1fe7067fe37"},
- {file = "rpds_py-0.28.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bcf1d210dfee61a6c86551d67ee1031899c0fdbae88b2d44a569995d43797712"},
- {file = "rpds_py-0.28.0-cp313-cp313t-win32.whl", hash = "sha256:3aa4dc0fdab4a7029ac63959a3ccf4ed605fee048ba67ce89ca3168da34a1342"},
- {file = "rpds_py-0.28.0-cp313-cp313t-win_amd64.whl", hash = "sha256:7b7d9d83c942855e4fdcfa75d4f96f6b9e272d42fffcb72cd4bb2577db2e2907"},
- {file = "rpds_py-0.28.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:dcdcb890b3ada98a03f9f2bb108489cdc7580176cb73b4f2d789e9a1dac1d472"},
- {file = "rpds_py-0.28.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f274f56a926ba2dc02976ca5b11c32855cbd5925534e57cfe1fda64e04d1add2"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fe0438ac4a29a520ea94c8c7f1754cdd8feb1bc490dfda1bfd990072363d527"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a358a32dd3ae50e933347889b6af9a1bdf207ba5d1a3f34e1a38cd3540e6733"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e80848a71c78aa328fefaba9c244d588a342c8e03bda518447b624ea64d1ff56"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f586db2e209d54fe177e58e0bc4946bea5fb0102f150b1b2f13de03e1f0976f8"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ae8ee156d6b586e4292491e885d41483136ab994e719a13458055bec14cf370"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:a805e9b3973f7e27f7cab63a6b4f61d90f2e5557cff73b6e97cd5b8540276d3d"},
- {file = "rpds_py-0.28.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5d3fd16b6dc89c73a4da0b4ac8b12a7ecc75b2864b95c9e5afed8003cb50a728"},
- {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:6796079e5d24fdaba6d49bda28e2c47347e89834678f2bc2c1b4fc1489c0fb01"},
- {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:76500820c2af232435cbe215e3324c75b950a027134e044423f59f5b9a1ba515"},
- {file = "rpds_py-0.28.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bbdc5640900a7dbf9dd707fe6388972f5bbd883633eb68b76591044cfe346f7e"},
- {file = "rpds_py-0.28.0-cp314-cp314-win32.whl", hash = "sha256:adc8aa88486857d2b35d75f0640b949759f79dc105f50aa2c27816b2e0dd749f"},
- {file = "rpds_py-0.28.0-cp314-cp314-win_amd64.whl", hash = "sha256:66e6fa8e075b58946e76a78e69e1a124a21d9a48a5b4766d15ba5b06869d1fa1"},
- {file = "rpds_py-0.28.0-cp314-cp314-win_arm64.whl", hash = "sha256:a6fe887c2c5c59413353b7c0caff25d0e566623501ccfff88957fa438a69377d"},
- {file = "rpds_py-0.28.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7a69df082db13c7070f7b8b1f155fa9e687f1d6aefb7b0e3f7231653b79a067b"},
- {file = "rpds_py-0.28.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b1cde22f2c30ebb049a9e74c5374994157b9b70a16147d332f89c99c5960737a"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5338742f6ba7a51012ea470bd4dc600a8c713c0c72adaa0977a1b1f4327d6592"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1460ebde1bcf6d496d80b191d854adedcc619f84ff17dc1c6d550f58c9efbba"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e3eb248f2feba84c692579257a043a7699e28a77d86c77b032c1d9fbb3f0219c"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3bbba5def70b16cd1c1d7255666aad3b290fbf8d0fe7f9f91abafb73611a91"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3114f4db69ac5a1f32e7e4d1cbbe7c8f9cf8217f78e6e002cedf2d54c2a548ed"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4b0cb8a906b1a0196b863d460c0222fb8ad0f34041568da5620f9799b83ccf0b"},
- {file = "rpds_py-0.28.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf681ac76a60b667106141e11a92a3330890257e6f559ca995fbb5265160b56e"},
- {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1e8ee6413cfc677ce8898d9cde18cc3a60fc2ba756b0dec5b71eb6eb21c49fa1"},
- {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b3072b16904d0b5572a15eb9d31c1954e0d3227a585fc1351aa9878729099d6c"},
- {file = "rpds_py-0.28.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b670c30fd87a6aec281c3c9896d3bae4b205fd75d79d06dc87c2503717e46092"},
- {file = "rpds_py-0.28.0-cp314-cp314t-win32.whl", hash = "sha256:8014045a15b4d2b3476f0a287fcc93d4f823472d7d1308d47884ecac9e612be3"},
- {file = "rpds_py-0.28.0-cp314-cp314t-win_amd64.whl", hash = "sha256:7a4e59c90d9c27c561eb3160323634a9ff50b04e4f7820600a2beb0ac90db578"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f5e7101145427087e493b9c9b959da68d357c28c562792300dd21a095118ed16"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:31eb671150b9c62409a888850aaa8e6533635704fe2b78335f9aaf7ff81eec4d"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b55c1f64482f7d8bd39942f376bfdf2f6aec637ee8c805b5041e14eeb771db"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24743a7b372e9a76171f6b69c01aedf927e8ac3e16c474d9fe20d552a8cb45c7"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:389c29045ee8bbb1627ea190b4976a310a295559eaf9f1464a1a6f2bf84dde78"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23690b5827e643150cf7b49569679ec13fe9a610a15949ed48b85eb7f98f34ec"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f0c9266c26580e7243ad0d72fc3e01d6b33866cfab5084a6da7576bcf1c4f72"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4c6c4db5d73d179746951486df97fd25e92396be07fc29ee8ff9a8f5afbdfb27"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a3b695a8fa799dd2cfdb4804b37096c5f6dba1ac7f48a7fbf6d0485bcd060316"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:6aa1bfce3f83baf00d9c5fcdbba93a3ab79958b4c7d7d1f55e7fe68c20e63912"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b0f9dceb221792b3ee6acb5438eb1f02b0cb2c247796a72b016dcc92c6de829"},
- {file = "rpds_py-0.28.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:5d0145edba8abd3db0ab22b5300c99dc152f5c9021fab861be0f0544dc3cbc5f"},
- {file = "rpds_py-0.28.0.tar.gz", hash = "sha256:abd4df20485a0983e2ca334a216249b6186d6e3c1627e106651943dbdb791aea"},
-]
-
-[[package]]
-name = "rsa"
-version = "4.9.1"
-description = "Pure-Python RSA implementation"
-optional = false
-python-versions = "<4,>=3.6"
-groups = ["main"]
-files = [
- {file = "rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762"},
- {file = "rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75"},
-]
-
-[package.dependencies]
-pyasn1 = ">=0.1.3"
-
-[[package]]
-name = "s3transfer"
-version = "0.14.0"
-description = "An Amazon S3 Transfer Manager"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:ea3b790c7077558ed1f02a3072fb3cb992bbbd253392f4b6e9e8976941c7d456"},
- {file = "s3transfer-0.14.0.tar.gz", hash = "sha256:eff12264e7c8b4985074ccce27a3b38a485bb7f7422cc8046fee9be4983e4125"},
-]
-
-[package.dependencies]
-botocore = ">=1.37.4,<2.0a0"
-
-[package.extras]
-crt = ["botocore[crt] (>=1.37.4,<2.0a0)"]
-
-[[package]]
-name = "sentry-sdk"
-version = "2.44.0"
-description = "Python client for Sentry (https://sentry.io)"
-optional = false
-python-versions = ">=3.6"
-groups = ["dev"]
-files = [
- {file = "sentry_sdk-2.44.0-py2.py3-none-any.whl", hash = "sha256:9e36a0372b881e8f92fdbff4564764ce6cec4b7f25424d0a3a8d609c9e4651a7"},
- {file = "sentry_sdk-2.44.0.tar.gz", hash = "sha256:5b1fe54dfafa332e900b07dd8f4dfe35753b64e78e7d9b1655a28fd3065e2493"},
-]
-
-[package.dependencies]
-certifi = "*"
-urllib3 = ">=1.26.11"
-
-[package.extras]
-aiohttp = ["aiohttp (>=3.5)"]
-anthropic = ["anthropic (>=0.16)"]
-arq = ["arq (>=0.23)"]
-asyncpg = ["asyncpg (>=0.23)"]
-beam = ["apache-beam (>=2.12)"]
-bottle = ["bottle (>=0.12.13)"]
-celery = ["celery (>=3)"]
-celery-redbeat = ["celery-redbeat (>=2)"]
-chalice = ["chalice (>=1.16.0)"]
-clickhouse-driver = ["clickhouse-driver (>=0.2.0)"]
-django = ["django (>=1.8)"]
-falcon = ["falcon (>=1.4)"]
-fastapi = ["fastapi (>=0.79.0)"]
-flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
-google-genai = ["google-genai (>=1.29.0)"]
-grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"]
-http2 = ["httpcore[http2] (==1.*)"]
-httpx = ["httpx (>=0.16.0)"]
-huey = ["huey (>=2)"]
-huggingface-hub = ["huggingface_hub (>=0.22)"]
-langchain = ["langchain (>=0.0.210)"]
-langgraph = ["langgraph (>=0.6.6)"]
-launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"]
-litellm = ["litellm (>=1.77.5)"]
-litestar = ["litestar (>=2.0.0)"]
-loguru = ["loguru (>=0.5)"]
-mcp = ["mcp (>=1.15.0)"]
-openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"]
-openfeature = ["openfeature-sdk (>=0.7.1)"]
-opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
-opentelemetry-experimental = ["opentelemetry-distro"]
-pure-eval = ["asttokens", "executing", "pure_eval"]
-pydantic-ai = ["pydantic-ai (>=1.0.0)"]
-pymongo = ["pymongo (>=3.1)"]
-pyspark = ["pyspark (>=2.4.4)"]
-quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
-rq = ["rq (>=0.6)"]
-sanic = ["sanic (>=0.8)"]
-sqlalchemy = ["sqlalchemy (>=1.2)"]
-starlette = ["starlette (>=0.19.1)"]
-starlite = ["starlite (>=1.48)"]
-statsig = ["statsig (>=0.55.3)"]
-tornado = ["tornado (>=6)"]
-unleash = ["UnleashClient (>=6.0.1)"]
-
-[[package]]
-name = "setuptools"
-version = "80.9.0"
-description = "Easily download, build, install, upgrade, and uninstall Python packages"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "test"]
-files = [
- {file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"},
- {file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"},
-]
-
-[package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
-core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"]
-cover = ["pytest-cov"]
-doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
-enabler = ["pytest-enabler (>=2.2)"]
-test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"]
-type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"]
-
-[[package]]
-name = "sf-hamilton"
-version = "1.89.0"
-description = "Hamilton, the micro-framework for creating dataframes."
-optional = false
-python-versions = "<4,>=3.8.1"
-groups = ["main"]
-files = [
- {file = "sf_hamilton-1.89.0-py3-none-any.whl", hash = "sha256:25c0efeb498cd1847aec5fbde2e69b4756c4e0c2a5238bbedbe2178d559fd677"},
- {file = "sf_hamilton-1.89.0.tar.gz", hash = "sha256:dec10455ce5dacd9402c7c8325c2eb2959c0f96f912dfcf2c999ef556421d2d2"},
-]
-
-[package.dependencies]
-numpy = "*"
-pandas = "*"
-typing_extensions = ">4.0.0"
-typing_inspect = "*"
-
-[package.extras]
-cli = ["typer"]
-dask = ["dask[complete]"]
-dask-array = ["dask[array]"]
-dask-dataframe = ["dask[dataframe]"]
-dask-diagnostics = ["dask[diagnostics]"]
-dask-distributed = ["dask[distributed]"]
-datadog = ["ddtrace (<3.0)"]
-diskcache = ["diskcache"]
-experiments = ["fastapi", "fastui", "uvicorn"]
-lsp = ["sf-hamilton-lsp"]
-openlineage = ["openlineage-python"]
-pandera = ["pandera"]
-pydantic = ["pydantic (>=2.0)"]
-pyspark = ["pyspark[pandas-on-spark,sql]"]
-ray = ["pyarrow", "ray (>=2.0.0)"]
-rich = ["rich"]
-sdk = ["sf-hamilton-sdk"]
-slack = ["slack-sdk"]
-tqdm = ["tqdm"]
-ui = ["sf-hamilton-ui"]
-vaex = ["vaex ; python_version <= \"3.10\""]
-visualization = ["graphviz", "networkx"]
-
-[[package]]
-name = "shellingham"
-version = "1.5.4"
-description = "Tool to Detect Surrounding Shell"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev"]
-files = [
- {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
- {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
-]
-
-[[package]]
-name = "simple-websocket"
-version = "1.1.0"
-description = "Simple WebSocket server and client for Python"
-optional = false
-python-versions = ">=3.6"
-groups = ["test"]
-files = [
- {file = "simple_websocket-1.1.0-py3-none-any.whl", hash = "sha256:4af6069630a38ed6c561010f0e11a5bc0d4ca569b36306eb257cd9a192497c8c"},
- {file = "simple_websocket-1.1.0.tar.gz", hash = "sha256:7939234e7aa067c534abdab3a9ed933ec9ce4691b0713c78acb195560aa52ae4"},
-]
-
-[package.dependencies]
-wsproto = "*"
-
-[package.extras]
-dev = ["flake8", "pytest", "pytest-cov", "tox"]
-docs = ["sphinx"]
-
-[[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", "dev", "eval"]
-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 = "smmap"
-version = "5.0.2"
-description = "A pure Python implementation of a sliding window memory map manager"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev", "eval"]
-files = [
- {file = "smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e"},
- {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"},
-]
-
-[[package]]
-name = "sniffio"
-version = "1.3.1"
-description = "Sniff out which async library your code is running under"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev"]
-files = [
- {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
- {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
-]
-
-[[package]]
-name = "soupsieve"
-version = "2.8"
-description = "A modern CSS selector implementation for Beautiful Soup."
-optional = false
-python-versions = ">=3.9"
-groups = ["eval"]
-files = [
- {file = "soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c"},
- {file = "soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f"},
-]
-
-[[package]]
-name = "sqlalchemy"
-version = "2.0.44"
-description = "Database Abstraction Library"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev"]
-files = [
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:471733aabb2e4848d609141a9e9d56a427c0a038f4abf65dd19d7a21fd563632"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48bf7d383a35e668b984c805470518b635d48b95a3c57cb03f37eaa3551b5f9f"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bf4bb6b3d6228fcf3a71b50231199fb94d2dd2611b66d33be0578ea3e6c2726"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:e998cf7c29473bd077704cea3577d23123094311f59bdc4af551923b168332b1"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:ebac3f0b5732014a126b43c2b7567f2f0e0afea7d9119a3378bde46d3dcad88e"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-win32.whl", hash = "sha256:3255d821ee91bdf824795e936642bbf43a4c7cedf5d1aed8d24524e66843aa74"},
- {file = "SQLAlchemy-2.0.44-cp37-cp37m-win_amd64.whl", hash = "sha256:78e6c137ba35476adb5432103ae1534f2f5295605201d946a4198a0dea4b38e7"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c77f3080674fc529b1bd99489378c7f63fcb4ba7f8322b79732e0258f0ea3ce"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c26ef74ba842d61635b0152763d057c8d48215d5be9bb8b7604116a059e9985"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4a172b31785e2f00780eccab00bc240ccdbfdb8345f1e6063175b3ff12ad1b0"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9480c0740aabd8cb29c329b422fb65358049840b34aba0adf63162371d2a96e"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:17835885016b9e4d0135720160db3095dc78c583e7b902b6be799fb21035e749"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cbe4f85f50c656d753890f39468fcd8190c5f08282caf19219f684225bfd5fd2"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-win32.whl", hash = "sha256:2fcc4901a86ed81dc76703f3b93ff881e08761c63263c46991081fd7f034b165"},
- {file = "sqlalchemy-2.0.44-cp310-cp310-win_amd64.whl", hash = "sha256:9919e77403a483ab81e3423151e8ffc9dd992c20d2603bf17e4a8161111e55f5"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fe3917059c7ab2ee3f35e77757062b1bea10a0b6ca633c58391e3f3c6c488dd"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:de4387a354ff230bc979b46b2207af841dc8bf29847b6c7dbe60af186d97aefa"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3678a0fb72c8a6a29422b2732fe423db3ce119c34421b5f9955873eb9b62c1e"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cf6872a23601672d61a68f390e44703442639a12ee9dd5a88bbce52a695e46e"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:329aa42d1be9929603f406186630135be1e7a42569540577ba2c69952b7cf399"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:70e03833faca7166e6a9927fbee7c27e6ecde436774cd0b24bbcc96353bce06b"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-win32.whl", hash = "sha256:253e2f29843fb303eca6b2fc645aca91fa7aa0aa70b38b6950da92d44ff267f3"},
- {file = "sqlalchemy-2.0.44-cp311-cp311-win_amd64.whl", hash = "sha256:7a8694107eb4308a13b425ca8c0e67112f8134c846b6e1f722698708741215d5"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72fea91746b5890f9e5e0997f16cbf3d53550580d76355ba2d998311b17b2250"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:585c0c852a891450edbb1eaca8648408a3cc125f18cf433941fa6babcc359e29"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b94843a102efa9ac68a7a30cd46df3ff1ed9c658100d30a725d10d9c60a2f44"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:119dc41e7a7defcefc57189cfa0e61b1bf9c228211aba432b53fb71ef367fda1"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0765e318ee9179b3718c4fd7ba35c434f4dd20332fbc6857a5e8df17719c24d7"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e7b5b079055e02d06a4308d0481658e4f06bc7ef211567edc8f7d5dce52018d"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-win32.whl", hash = "sha256:846541e58b9a81cce7dee8329f352c318de25aa2f2bbe1e31587eb1f057448b4"},
- {file = "sqlalchemy-2.0.44-cp312-cp312-win_amd64.whl", hash = "sha256:7cbcb47fd66ab294703e1644f78971f6f2f1126424d2b300678f419aa73c7b6e"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73"},
- {file = "sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2fc44e5965ea46909a416fff0af48a219faefd5773ab79e5f8a5fcd5d62b2667"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dc8b3850d2a601ca2320d081874033684e246d28e1c5e89db0864077cfc8f5a9"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d733dec0614bb8f4bcb7c8af88172b974f685a31dc3a65cca0527e3120de5606"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22be14009339b8bc16d6b9dc8780bacaba3402aa7581658e246114abbd2236e3"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:357bade0e46064f88f2c3a99808233e67b0051cdddf82992379559322dfeb183"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4848395d932e93c1595e59a8672aa7400e8922c39bb9b0668ed99ac6fa867822"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-win32.whl", hash = "sha256:2f19644f27c76f07e10603580a47278abb2a70311136a7f8fd27dc2e096b9013"},
- {file = "sqlalchemy-2.0.44-cp38-cp38-win_amd64.whl", hash = "sha256:1df4763760d1de0dfc8192cc96d8aa293eb1a44f8f7a5fbe74caf1b551905c5e"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f7027414f2b88992877573ab780c19ecb54d3a536bef3397933573d6b5068be4"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fe166c7d00912e8c10d3a9a0ce105569a31a3d0db1a6e82c4e0f4bf16d5eca9"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3caef1ff89b1caefc28f0368b3bde21a7e3e630c2eddac16abd9e47bd27cc36a"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc2856d24afa44295735e72f3c75d6ee7fdd4336d8d3a8f3d44de7aa6b766df2"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:11bac86b0deada30b6b5f93382712ff0e911fe8d31cb9bf46e6b149ae175eff0"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4d18cd0e9a0f37c9f4088e50e3839fcb69a380a0ec957408e0b57cff08ee0a26"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-win32.whl", hash = "sha256:9e9018544ab07614d591a26c1bd4293ddf40752cc435caf69196740516af7100"},
- {file = "sqlalchemy-2.0.44-cp39-cp39-win_amd64.whl", hash = "sha256:8e0e4e66fd80f277a8c3de016a81a554e76ccf6b8d881ee0b53200305a8433f6"},
- {file = "sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05"},
- {file = "sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22"},
-]
-
-[package.dependencies]
-greenlet = {version = ">=1", 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\""}
-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 = "sqlparse"
-version = "0.5.5"
-description = "A non-validating SQL parser."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "sqlparse-0.5.5-py3-none-any.whl", hash = "sha256:12a08b3bf3eec877c519589833aed092e2444e68240a3577e8e26148acc7b1ba"},
- {file = "sqlparse-0.5.5.tar.gz", hash = "sha256:e20d4a9b0b8585fdf63b10d30066c7c94c5d7a7ec47c889a2d83a3caa93ff28e"},
-]
-
-[package.extras]
-dev = ["build"]
-doc = ["sphinx"]
-
-[[package]]
-name = "sseclient-py"
-version = "1.8.0"
-description = "SSE client for Python"
-optional = false
-python-versions = "*"
-groups = ["dev"]
-files = [
- {file = "sseclient-py-1.8.0.tar.gz", hash = "sha256:c547c5c1a7633230a38dc599a21a2dc638f9b5c297286b48b46b935c71fac3e8"},
- {file = "sseclient_py-1.8.0-py2.py3-none-any.whl", hash = "sha256:4ecca6dc0b9f963f8384e9d7fd529bf93dd7d708144c4fb5da0e0a1a926fee83"},
-]
-
-[[package]]
-name = "stack-data"
-version = "0.6.3"
-description = "Extract data from python stack frames and tracebacks for informative displays"
-optional = false
-python-versions = "*"
-groups = ["eval"]
-files = [
- {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
- {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
-]
-
-[package.dependencies]
-asttokens = ">=2.1.0"
-executing = ">=1.2.0"
-pure-eval = "*"
-
-[package.extras]
-tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"]
-
-[[package]]
-name = "starlette"
-version = "0.49.3"
-description = "The little ASGI library that shines."
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "starlette-0.49.3-py3-none-any.whl", hash = "sha256:b579b99715fdc2980cf88c8ec96d3bf1ce16f5a8051a7c2b84ef9b1cdecaea2f"},
- {file = "starlette-0.49.3.tar.gz", hash = "sha256:1c14546f299b5901a1ea0e34410575bc33bbd741377a10484a54445588d00284"},
-]
-
-[package.dependencies]
-anyio = ">=3.6.2,<5"
-typing-extensions = {version = ">=4.10.0", markers = "python_version < \"3.13\""}
-
-[package.extras]
-full = ["httpx (>=0.27.0,<0.29.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.18)", "pyyaml"]
-
-[[package]]
-name = "streamlit"
-version = "1.51.0"
-description = "A faster way to build and share data apps"
-optional = false
-python-versions = ">=3.10"
-groups = ["dev", "eval"]
-files = [
- {file = "streamlit-1.51.0-py3-none-any.whl", hash = "sha256:4008b029f71401ce54946bb09a6a3e36f4f7652cbb48db701224557738cfda38"},
- {file = "streamlit-1.51.0.tar.gz", hash = "sha256:1e742a9c0b698f466c6f5bf58d333beda5a1fbe8de660743976791b5c1446ef6"},
-]
-
-[package.dependencies]
-altair = ">=4.0,<5.4.0 || >5.4.0,<5.4.1 || >5.4.1,<6"
-blinker = ">=1.5.0,<2"
-cachetools = ">=4.0,<7"
-click = ">=7.0,<9"
-gitpython = ">=3.0.7,<3.1.19 || >3.1.19,<4"
-numpy = ">=1.23,<3"
-packaging = ">=20,<26"
-pandas = ">=1.4.0,<3"
-pillow = ">=7.1.0,<13"
-protobuf = ">=3.20,<7"
-pyarrow = ">=7.0,<22"
-pydeck = ">=0.8.0b4,<1"
-requests = ">=2.27,<3"
-tenacity = ">=8.1.0,<10"
-toml = ">=0.10.1,<2"
-tornado = ">=6.0.3,<6.5.0 || >6.5.0,<7"
-typing-extensions = ">=4.4.0,<5"
-watchdog = {version = ">=2.1.5,<7", markers = "platform_system != \"Darwin\""}
-
-[package.extras]
-all = ["rich (>=11.0.0)", "streamlit[auth,charts,pdf,snowflake,sql]"]
-auth = ["Authlib (>=1.3.2)"]
-charts = ["graphviz (>=0.19.0)", "matplotlib (>=3.0.0)", "orjson (>=3.5.0)", "plotly (>=4.0.0)"]
-pdf = ["streamlit-pdf (>=1.0.0)"]
-snowflake = ["snowflake-connector-python (>=3.3.0) ; python_version < \"3.12\"", "snowflake-snowpark-python[modin] (>=1.17.0) ; python_version < \"3.12\""]
-sql = ["SQLAlchemy (>=2.0.0)"]
-
-[[package]]
-name = "streamlit-tags"
-version = "1.2.8"
-description = "Tags custom component for Streamlit"
-optional = false
-python-versions = ">=3.6"
-groups = ["eval"]
-files = [
- {file = "streamlit_tags-1.2.8-py3-none-any.whl", hash = "sha256:c71b10666f3fce67d8e0b3c089aa50dc48830d310223fb88005b08f157586f95"},
- {file = "streamlit_tags-1.2.8.tar.gz", hash = "sha256:9ea46b21f206dc73164e59e3c800a96c863c90af57afde20115f001a6d986583"},
-]
-
-[package.dependencies]
-streamlit = ">=0.63"
-
-[[package]]
-name = "tabulate"
-version = "0.9.0"
-description = "Pretty-print tabular data"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev"]
-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 = "8.4.2"
-description = "Retry code until it succeeds"
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "tenacity-8.4.2-py3-none-any.whl", hash = "sha256:9e6f7cf7da729125c7437222f8a522279751cdfbe6b67bfe64f75d3a348661b2"},
- {file = "tenacity-8.4.2.tar.gz", hash = "sha256:cd80a53a79336edba8489e767f729e4f391c896956b57140b5d7511a64bbd3ef"},
-]
-
-[package.extras]
-doc = ["reno", "sphinx"]
-test = ["pytest", "tornado (>=4.5)", "typeguard"]
-
-[[package]]
-name = "tiktoken"
-version = "0.12.0"
-description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "tiktoken-0.12.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3de02f5a491cfd179aec916eddb70331814bd6bf764075d39e21d5862e533970"},
- {file = "tiktoken-0.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b6cfb6d9b7b54d20af21a912bfe63a2727d9cfa8fbda642fd8322c70340aad16"},
- {file = "tiktoken-0.12.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:cde24cdb1b8a08368f709124f15b36ab5524aac5fa830cc3fdce9c03d4fb8030"},
- {file = "tiktoken-0.12.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6de0da39f605992649b9cfa6f84071e3f9ef2cec458d08c5feb1b6f0ff62e134"},
- {file = "tiktoken-0.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6faa0534e0eefbcafaccb75927a4a380463a2eaa7e26000f0173b920e98b720a"},
- {file = "tiktoken-0.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:82991e04fc860afb933efb63957affc7ad54f83e2216fe7d319007dab1ba5892"},
- {file = "tiktoken-0.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:6fb2995b487c2e31acf0a9e17647e3b242235a20832642bb7a9d1a181c0c1bb1"},
- {file = "tiktoken-0.12.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6e227c7f96925003487c33b1b32265fad2fbcec2b7cf4817afb76d416f40f6bb"},
- {file = "tiktoken-0.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c06cf0fcc24c2cb2adb5e185c7082a82cba29c17575e828518c2f11a01f445aa"},
- {file = "tiktoken-0.12.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:f18f249b041851954217e9fd8e5c00b024ab2315ffda5ed77665a05fa91f42dc"},
- {file = "tiktoken-0.12.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:47a5bc270b8c3db00bb46ece01ef34ad050e364b51d406b6f9730b64ac28eded"},
- {file = "tiktoken-0.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:508fa71810c0efdcd1b898fda574889ee62852989f7c1667414736bcb2b9a4bd"},
- {file = "tiktoken-0.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1af81a6c44f008cba48494089dd98cccb8b313f55e961a52f5b222d1e507967"},
- {file = "tiktoken-0.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e68e3e593637b53e56f7237be560f7a394451cb8c11079755e80ae64b9e6def"},
- {file = "tiktoken-0.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b97f74aca0d78a1ff21b8cd9e9925714c15a9236d6ceacf5c7327c117e6e21e8"},
- {file = "tiktoken-0.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b90f5ad190a4bb7c3eb30c5fa32e1e182ca1ca79f05e49b448438c3e225a49b"},
- {file = "tiktoken-0.12.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:65b26c7a780e2139e73acc193e5c63ac754021f160df919add909c1492c0fb37"},
- {file = "tiktoken-0.12.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:edde1ec917dfd21c1f2f8046b86348b0f54a2c0547f68149d8600859598769ad"},
- {file = "tiktoken-0.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:35a2f8ddd3824608b3d650a000c1ef71f730d0c56486845705a8248da00f9fe5"},
- {file = "tiktoken-0.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83d16643edb7fa2c99eff2ab7733508aae1eebb03d5dfc46f5565862810f24e3"},
- {file = "tiktoken-0.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ffc5288f34a8bc02e1ea7047b8d041104791d2ddbf42d1e5fa07822cbffe16bd"},
- {file = "tiktoken-0.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:775c2c55de2310cc1bc9a3ad8826761cbdc87770e586fd7b6da7d4589e13dab3"},
- {file = "tiktoken-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a01b12f69052fbe4b080a2cfb867c4de12c704b56178edf1d1d7b273561db160"},
- {file = "tiktoken-0.12.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:01d99484dc93b129cd0964f9d34eee953f2737301f18b3c7257bf368d7615baa"},
- {file = "tiktoken-0.12.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:4a1a4fcd021f022bfc81904a911d3df0f6543b9e7627b51411da75ff2fe7a1be"},
- {file = "tiktoken-0.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:981a81e39812d57031efdc9ec59fa32b2a5a5524d20d4776574c4b4bd2e9014a"},
- {file = "tiktoken-0.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9baf52f84a3f42eef3ff4e754a0db79a13a27921b457ca9832cf944c6be4f8f3"},
- {file = "tiktoken-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:b8a0cd0c789a61f31bf44851defbd609e8dd1e2c8589c614cc1060940ef1f697"},
- {file = "tiktoken-0.12.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d5f89ea5680066b68bcb797ae85219c72916c922ef0fcdd3480c7d2315ffff16"},
- {file = "tiktoken-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b4e7ed1c6a7a8a60a3230965bdedba8cc58f68926b835e519341413370e0399a"},
- {file = "tiktoken-0.12.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:fc530a28591a2d74bce821d10b418b26a094bf33839e69042a6e86ddb7a7fb27"},
- {file = "tiktoken-0.12.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:06a9f4f49884139013b138920a4c393aa6556b2f8f536345f11819389c703ebb"},
- {file = "tiktoken-0.12.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:04f0e6a985d95913cabc96a741c5ffec525a2c72e9df086ff17ebe35985c800e"},
- {file = "tiktoken-0.12.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0ee8f9ae00c41770b5f9b0bb1235474768884ae157de3beb5439ca0fd70f3e25"},
- {file = "tiktoken-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:dc2dd125a62cb2b3d858484d6c614d136b5b848976794edfb63688d539b8b93f"},
- {file = "tiktoken-0.12.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a90388128df3b3abeb2bfd1895b0681412a8d7dc644142519e6f0a97c2111646"},
- {file = "tiktoken-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:da900aa0ad52247d8794e307d6446bd3cdea8e192769b56276695d34d2c9aa88"},
- {file = "tiktoken-0.12.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:285ba9d73ea0d6171e7f9407039a290ca77efcdb026be7769dccc01d2c8d7fff"},
- {file = "tiktoken-0.12.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:d186a5c60c6a0213f04a7a802264083dea1bbde92a2d4c7069e1a56630aef830"},
- {file = "tiktoken-0.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:604831189bd05480f2b885ecd2d1986dc7686f609de48208ebbbddeea071fc0b"},
- {file = "tiktoken-0.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8f317e8530bb3a222547b85a58583238c8f74fd7a7408305f9f63246d1a0958b"},
- {file = "tiktoken-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:399c3dd672a6406719d84442299a490420b458c44d3ae65516302a99675888f3"},
- {file = "tiktoken-0.12.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2c714c72bc00a38ca969dae79e8266ddec999c7ceccd603cc4f0d04ccd76365"},
- {file = "tiktoken-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cbb9a3ba275165a2cb0f9a83f5d7025afe6b9d0ab01a22b50f0e74fee2ad253e"},
- {file = "tiktoken-0.12.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:dfdfaa5ffff8993a3af94d1125870b1d27aed7cb97aa7eb8c1cefdbc87dbee63"},
- {file = "tiktoken-0.12.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:584c3ad3d0c74f5269906eb8a659c8bfc6144a52895d9261cdaf90a0ae5f4de0"},
- {file = "tiktoken-0.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:54c891b416a0e36b8e2045b12b33dd66fb34a4fe7965565f1b482da50da3e86a"},
- {file = "tiktoken-0.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5edb8743b88d5be814b1a8a8854494719080c28faaa1ccbef02e87354fe71ef0"},
- {file = "tiktoken-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f61c0aea5565ac82e2ec50a05e02a6c44734e91b51c10510b084ea1b8e633a71"},
- {file = "tiktoken-0.12.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:d51d75a5bffbf26f86554d28e78bfb921eae998edc2675650fd04c7e1f0cdc1e"},
- {file = "tiktoken-0.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:09eb4eae62ae7e4c62364d9ec3a57c62eea707ac9a2b2c5d6bd05de6724ea179"},
- {file = "tiktoken-0.12.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:df37684ace87d10895acb44b7f447d4700349b12197a526da0d4a4149fde074c"},
- {file = "tiktoken-0.12.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:4c9614597ac94bb294544345ad8cf30dac2129c05e2db8dc53e082f355857af7"},
- {file = "tiktoken-0.12.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:20cf97135c9a50de0b157879c3c4accbb29116bcf001283d26e073ff3b345946"},
- {file = "tiktoken-0.12.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:15d875454bbaa3728be39880ddd11a5a2a9e548c29418b41e8fd8a767172b5ec"},
- {file = "tiktoken-0.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cff3688ba3c639ebe816f8d58ffbbb0aa7433e23e08ab1cade5d175fc973fb3"},
- {file = "tiktoken-0.12.0.tar.gz", hash = "sha256:b18ba7ee2b093863978fcb14f74b3707cdc8d4d4d3836853ce7ec60772139931"},
-]
-
-[package.dependencies]
-regex = ">=2022.1.18"
-requests = ">=2.26.0"
-
-[package.extras]
-blobfile = ["blobfile (>=2)"]
-
-[[package]]
-name = "tokenizers"
-version = "0.22.2"
-description = ""
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c"},
- {file = "tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b"},
- {file = "tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67"},
- {file = "tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4"},
- {file = "tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a"},
- {file = "tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a"},
- {file = "tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5"},
- {file = "tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92"},
- {file = "tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48"},
- {file = "tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc"},
- {file = "tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:753d47ebd4542742ef9261d9da92cd545b2cacbb48349a1225466745bb866ec4"},
- {file = "tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e10bf9113d209be7cd046d40fbabbaf3278ff6d18eb4da4c500443185dc1896c"},
- {file = "tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64d94e84f6660764e64e7e0b22baa72f6cd942279fdbb21d46abd70d179f0195"},
- {file = "tokenizers-0.22.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f01a9c019878532f98927d2bacb79bbb404b43d3437455522a00a30718cdedb5"},
- {file = "tokenizers-0.22.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:319f659ee992222f04e58f84cbf407cfa66a65fe3a8de44e8ad2bc53e7d99012"},
- {file = "tokenizers-0.22.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e50f8554d504f617d9e9d6e4c2c2884a12b388a97c5c77f0bc6cf4cd032feee"},
- {file = "tokenizers-0.22.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a62ba2c5faa2dd175aaeed7b15abf18d20266189fb3406c5d0550dd34dd5f37"},
- {file = "tokenizers-0.22.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113"},
- {file = "tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917"},
-]
-
-[package.dependencies]
-huggingface-hub = ">=0.16.4,<2.0"
-
-[package.extras]
-dev = ["tokenizers[testing]"]
-docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
-testing = ["datasets", "numpy", "pytest", "pytest-asyncio", "requests", "ruff", "ty"]
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
- {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-
-[[package]]
-name = "tomlkit"
-version = "0.13.3"
-description = "Style preserving TOML library"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0"},
- {file = "tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1"},
-]
-
-[[package]]
-name = "tornado"
-version = "6.5.2"
-description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
-optional = false
-python-versions = ">=3.9"
-groups = ["dev", "eval"]
-files = [
- {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6"},
- {file = "tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef"},
- {file = "tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e"},
- {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882"},
- {file = "tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108"},
- {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c"},
- {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4"},
- {file = "tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04"},
- {file = "tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0"},
- {file = "tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f"},
- {file = "tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af"},
- {file = "tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0"},
-]
-
-[[package]]
-name = "tqdm"
-version = "4.67.1"
-description = "Fast, Extensible Progress Meter"
-optional = false
-python-versions = ">=3.7"
-groups = ["main", "dev", "eval"]
-files = [
- {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"},
- {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"},
-]
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[package.extras]
-dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"]
-discord = ["requests"]
-notebook = ["ipywidgets (>=6)"]
-slack = ["slack-sdk"]
-telegram = ["requests"]
-
-[[package]]
-name = "traitlets"
-version = "5.14.3"
-description = "Traitlets Python configuration system"
-optional = false
-python-versions = ">=3.8"
-groups = ["eval"]
-files = [
- {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"},
- {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"},
-]
-
-[package.extras]
-docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"]
-test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"]
-
-[[package]]
-name = "typer"
-version = "0.20.0"
-description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a"},
- {file = "typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37"},
-]
-
-[package.dependencies]
-click = ">=8.0.0"
-rich = ">=10.11.0"
-shellingham = ">=1.3.0"
-typing-extensions = ">=3.7.4.3"
-
-[[package]]
-name = "typer-slim"
-version = "0.20.0"
-description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
-optional = false
-python-versions = ">=3.8"
-groups = ["main", "dev"]
-files = [
- {file = "typer_slim-0.20.0-py3-none-any.whl", hash = "sha256:f42a9b7571a12b97dddf364745d29f12221865acef7a2680065f9bb29c7dc89d"},
- {file = "typer_slim-0.20.0.tar.gz", hash = "sha256:9fc6607b3c6c20f5c33ea9590cbeb17848667c51feee27d9e314a579ab07d1a3"},
-]
-
-[package.dependencies]
-click = ">=8.0.0"
-typing-extensions = ">=3.7.4.3"
-
-[package.extras]
-standard = ["rich (>=10.11.0)", "shellingham (>=1.3.0)"]
-
-[[package]]
-name = "typing-extensions"
-version = "4.15.0"
-description = "Backported and Experimental Type Hints for Python 3.9+"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
- {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
-]
-
-[[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.2"
-description = "Runtime typing introspection tools"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"},
- {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"},
-]
-
-[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", "dev", "eval"]
-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.6.3"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "eval", "test"]
-files = [
- {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
- {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""]
-h2 = ["h2 (>=4,<5)"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
-
-[[package]]
-name = "uvicorn"
-version = "0.29.0"
-description = "The lightning-fast ASGI server."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"},
- {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"},
-]
-
-[package.dependencies]
-click = ">=7.0"
-colorama = {version = ">=0.4", optional = true, markers = "sys_platform == \"win32\" and extra == \"standard\""}
-h11 = ">=0.8"
-httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
-python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
-pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
-uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
-watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
-websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
-
-[package.extras]
-standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1) ; sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\"", "watchfiles (>=0.13)", "websockets (>=10.4)"]
-
-[[package]]
-name = "uvloop"
-version = "0.22.1"
-description = "Fast implementation of asyncio event loop on top of libuv"
-optional = false
-python-versions = ">=3.8.1"
-groups = ["main"]
-markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\""
-files = [
- {file = "uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c"},
- {file = "uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792"},
- {file = "uvloop-0.22.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86"},
- {file = "uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd"},
- {file = "uvloop-0.22.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2"},
- {file = "uvloop-0.22.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec"},
- {file = "uvloop-0.22.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9"},
- {file = "uvloop-0.22.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77"},
- {file = "uvloop-0.22.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21"},
- {file = "uvloop-0.22.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702"},
- {file = "uvloop-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733"},
- {file = "uvloop-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473"},
- {file = "uvloop-0.22.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42"},
- {file = "uvloop-0.22.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6"},
- {file = "uvloop-0.22.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370"},
- {file = "uvloop-0.22.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4"},
- {file = "uvloop-0.22.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2"},
- {file = "uvloop-0.22.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0"},
- {file = "uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705"},
- {file = "uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8"},
- {file = "uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d"},
- {file = "uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e"},
- {file = "uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e"},
- {file = "uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad"},
- {file = "uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142"},
- {file = "uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74"},
- {file = "uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35"},
- {file = "uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25"},
- {file = "uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6"},
- {file = "uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079"},
- {file = "uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289"},
- {file = "uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3"},
- {file = "uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c"},
- {file = "uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21"},
- {file = "uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88"},
- {file = "uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e"},
- {file = "uvloop-0.22.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:80eee091fe128e425177fbd82f8635769e2f32ec9daf6468286ec57ec0313efa"},
- {file = "uvloop-0.22.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:017bd46f9e7b78e81606329d07141d3da446f8798c6baeec124260e22c262772"},
- {file = "uvloop-0.22.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3e5c6727a57cb6558592a95019e504f605d1c54eb86463ee9f7a2dbd411c820"},
- {file = "uvloop-0.22.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:57df59d8b48feb0e613d9b1f5e57b7532e97cbaf0d61f7aa9aa32221e84bc4b6"},
- {file = "uvloop-0.22.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:55502bc2c653ed2e9692e8c55cb95b397d33f9f2911e929dc97c4d6b26d04242"},
- {file = "uvloop-0.22.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4a968a72422a097b09042d5fa2c5c590251ad484acf910a651b4b620acd7f193"},
- {file = "uvloop-0.22.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b45649628d816c030dba3c80f8e2689bab1c89518ed10d426036cdc47874dfc4"},
- {file = "uvloop-0.22.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ea721dd3203b809039fcc2983f14608dae82b212288b346e0bfe46ec2fab0b7c"},
- {file = "uvloop-0.22.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ae676de143db2b2f60a9696d7eca5bb9d0dd6cc3ac3dad59a8ae7e95f9e1b54"},
- {file = "uvloop-0.22.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:17d4e97258b0172dfa107b89aa1eeba3016f4b1974ce85ca3ef6a66b35cbf659"},
- {file = "uvloop-0.22.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:05e4b5f86e621cf3927631789999e697e58f0d2d32675b67d9ca9eb0bca55743"},
- {file = "uvloop-0.22.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:286322a90bea1f9422a470d5d2ad82d38080be0a29c4dd9b3e6384320a4d11e7"},
- {file = "uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f"},
-]
-
-[package.extras]
-dev = ["Cython (>=3.0,<4.0)", "setuptools (>=60)"]
-docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx_rtd_theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"]
-test = ["aiohttp (>=3.10.5)", "flake8 (>=6.1,<7.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=25.3.0,<25.4.0)", "pycodestyle (>=2.11.0,<2.12.0)"]
-
-[[package]]
-name = "virtualenv"
-version = "20.36.1"
-description = "Virtual Python Environment builder"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev"]
-files = [
- {file = "virtualenv-20.36.1-py3-none-any.whl", hash = "sha256:575a8d6b124ef88f6f51d56d656132389f961062a9177016a50e4f507bbcc19f"},
- {file = "virtualenv-20.36.1.tar.gz", hash = "sha256:8befb5c81842c641f8ee658481e42641c68b5eab3521d8e092d18320902466ba"},
-]
-
-[package.dependencies]
-distlib = ">=0.3.7,<1"
-filelock = {version = ">=3.20.1,<4", markers = "python_version >= \"3.10\""}
-platformdirs = ">=3.9.1,<5"
-
-[package.extras]
-docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
-test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8) ; platform_python_implementation == \"PyPy\" or platform_python_implementation == \"GraalVM\" or platform_python_implementation == \"CPython\" and sys_platform == \"win32\" and python_version >= \"3.13\"", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10) ; platform_python_implementation == \"CPython\""]
-
-[[package]]
-name = "watchdog"
-version = "4.0.2"
-description = "Filesystem events monitoring"
-optional = false
-python-versions = ">=3.8"
-groups = ["dev", "eval"]
-files = [
- {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ede7f010f2239b97cc79e6cb3c249e72962404ae3865860855d5cbe708b0fd22"},
- {file = "watchdog-4.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2cffa171445b0efa0726c561eca9a27d00a1f2b83846dbd5a4f639c4f8ca8e1"},
- {file = "watchdog-4.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c50f148b31b03fbadd6d0b5980e38b558046b127dc483e5e4505fcef250f9503"},
- {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7c7d4bf585ad501c5f6c980e7be9c4f15604c7cc150e942d82083b31a7548930"},
- {file = "watchdog-4.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:914285126ad0b6eb2258bbbcb7b288d9dfd655ae88fa28945be05a7b475a800b"},
- {file = "watchdog-4.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:984306dc4720da5498b16fc037b36ac443816125a3705dfde4fd90652d8028ef"},
- {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1cdcfd8142f604630deef34722d695fb455d04ab7cfe9963055df1fc69e6727a"},
- {file = "watchdog-4.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7ab624ff2f663f98cd03c8b7eedc09375a911794dfea6bf2a359fcc266bff29"},
- {file = "watchdog-4.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:132937547a716027bd5714383dfc40dc66c26769f1ce8a72a859d6a48f371f3a"},
- {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd67c7df93eb58f360c43802acc945fa8da70c675b6fa37a241e17ca698ca49b"},
- {file = "watchdog-4.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcfd02377be80ef3b6bc4ce481ef3959640458d6feaae0bd43dd90a43da90a7d"},
- {file = "watchdog-4.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:980b71510f59c884d684b3663d46e7a14b457c9611c481e5cef08f4dd022eed7"},
- {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aa160781cafff2719b663c8a506156e9289d111d80f3387cf3af49cedee1f040"},
- {file = "watchdog-4.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f6ee8dedd255087bc7fe82adf046f0b75479b989185fb0bdf9a98b612170eac7"},
- {file = "watchdog-4.0.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0b4359067d30d5b864e09c8597b112fe0a0a59321a0f331498b013fb097406b4"},
- {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:770eef5372f146997638d737c9a3c597a3b41037cfbc5c41538fc27c09c3a3f9"},
- {file = "watchdog-4.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeea812f38536a0aa859972d50c76e37f4456474b02bd93674d1947cf1e39578"},
- {file = "watchdog-4.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b2c45f6e1e57ebb4687690c05bc3a2c1fb6ab260550c4290b8abb1335e0fd08b"},
- {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:10b6683df70d340ac3279eff0b2766813f00f35a1d37515d2c99959ada8f05fa"},
- {file = "watchdog-4.0.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7c739888c20f99824f7aa9d31ac8a97353e22d0c0e54703a547a218f6637eb3"},
- {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c100d09ac72a8a08ddbf0629ddfa0b8ee41740f9051429baa8e31bb903ad7508"},
- {file = "watchdog-4.0.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f5315a8c8dd6dd9425b974515081fc0aadca1d1d61e078d2246509fd756141ee"},
- {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:2d468028a77b42cc685ed694a7a550a8d1771bb05193ba7b24006b8241a571a1"},
- {file = "watchdog-4.0.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f15edcae3830ff20e55d1f4e743e92970c847bcddc8b7509bcd172aa04de506e"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:936acba76d636f70db8f3c66e76aa6cb5136a936fc2a5088b9ce1c7a3508fc83"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_armv7l.whl", hash = "sha256:e252f8ca942a870f38cf785aef420285431311652d871409a64e2a0a52a2174c"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_i686.whl", hash = "sha256:0e83619a2d5d436a7e58a1aea957a3c1ccbf9782c43c0b4fed80580e5e4acd1a"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64.whl", hash = "sha256:88456d65f207b39f1981bf772e473799fcdc10801062c36fd5ad9f9d1d463a73"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:32be97f3b75693a93c683787a87a0dc8db98bb84701539954eef991fb35f5fbc"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:c82253cfc9be68e3e49282831afad2c1f6593af80c0daf1287f6a92657986757"},
- {file = "watchdog-4.0.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c0b14488bd336c5b1845cee83d3e631a1f8b4e9c5091ec539406e4a324f882d8"},
- {file = "watchdog-4.0.2-py3-none-win32.whl", hash = "sha256:0d8a7e523ef03757a5aa29f591437d64d0d894635f8a50f370fe37f913ce4e19"},
- {file = "watchdog-4.0.2-py3-none-win_amd64.whl", hash = "sha256:c344453ef3bf875a535b0488e3ad28e341adbd5a9ffb0f7d62cefacc8824ef2b"},
- {file = "watchdog-4.0.2-py3-none-win_ia64.whl", hash = "sha256:baececaa8edff42cd16558a639a9b0ddf425f93d892e8392a56bf904f5eff22c"},
- {file = "watchdog-4.0.2.tar.gz", hash = "sha256:b4dfbb6c49221be4535623ea4474a4d6ee0a9cef4a80b20c28db4d858b64e270"},
-]
-markers = {eval = "platform_system != \"Darwin\""}
-
-[package.extras]
-watchmedo = ["PyYAML (>=3.10)"]
-
-[[package]]
-name = "watchfiles"
-version = "1.1.1"
-description = "Simple, modern and high performance file watching and code reload in python."
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "watchfiles-1.1.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c"},
- {file = "watchfiles-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863"},
- {file = "watchfiles-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab"},
- {file = "watchfiles-1.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82"},
- {file = "watchfiles-1.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4"},
- {file = "watchfiles-1.1.1-cp310-cp310-win32.whl", hash = "sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844"},
- {file = "watchfiles-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e"},
- {file = "watchfiles-1.1.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5"},
- {file = "watchfiles-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff"},
- {file = "watchfiles-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606"},
- {file = "watchfiles-1.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701"},
- {file = "watchfiles-1.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10"},
- {file = "watchfiles-1.1.1-cp311-cp311-win32.whl", hash = "sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849"},
- {file = "watchfiles-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4"},
- {file = "watchfiles-1.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e"},
- {file = "watchfiles-1.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d"},
- {file = "watchfiles-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb"},
- {file = "watchfiles-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803"},
- {file = "watchfiles-1.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94"},
- {file = "watchfiles-1.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43"},
- {file = "watchfiles-1.1.1-cp312-cp312-win32.whl", hash = "sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9"},
- {file = "watchfiles-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9"},
- {file = "watchfiles-1.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404"},
- {file = "watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18"},
- {file = "watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae"},
- {file = "watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d"},
- {file = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b"},
- {file = "watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374"},
- {file = "watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0"},
- {file = "watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42"},
- {file = "watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18"},
- {file = "watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da"},
- {file = "watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04"},
- {file = "watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77"},
- {file = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef"},
- {file = "watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf"},
- {file = "watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5"},
- {file = "watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510"},
- {file = "watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05"},
- {file = "watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6"},
- {file = "watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81"},
- {file = "watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b"},
- {file = "watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a"},
- {file = "watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02"},
- {file = "watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21"},
- {file = "watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc"},
- {file = "watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c"},
- {file = "watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099"},
- {file = "watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01"},
- {file = "watchfiles-1.1.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70"},
- {file = "watchfiles-1.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2"},
- {file = "watchfiles-1.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02"},
- {file = "watchfiles-1.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be"},
- {file = "watchfiles-1.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f"},
- {file = "watchfiles-1.1.1-cp39-cp39-win32.whl", hash = "sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b"},
- {file = "watchfiles-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957"},
- {file = "watchfiles-1.1.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3"},
- {file = "watchfiles-1.1.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2"},
- {file = "watchfiles-1.1.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d"},
- {file = "watchfiles-1.1.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b"},
- {file = "watchfiles-1.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88"},
- {file = "watchfiles-1.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336"},
- {file = "watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24"},
- {file = "watchfiles-1.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49"},
- {file = "watchfiles-1.1.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f"},
- {file = "watchfiles-1.1.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34"},
- {file = "watchfiles-1.1.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc"},
- {file = "watchfiles-1.1.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e"},
- {file = "watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2"},
-]
-
-[package.dependencies]
-anyio = ">=3.0.0"
-
-[[package]]
-name = "wcwidth"
-version = "0.2.14"
-description = "Measures the displayed width of unicode strings in a terminal"
-optional = false
-python-versions = ">=3.6"
-groups = ["eval"]
-files = [
- {file = "wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1"},
- {file = "wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605"},
-]
-
-[[package]]
-name = "websocket-client"
-version = "1.9.0"
-description = "WebSocket client for Python with low level API options"
-optional = false
-python-versions = ">=3.9"
-groups = ["test"]
-files = [
- {file = "websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef"},
- {file = "websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98"},
-]
-
-[package.extras]
-docs = ["Sphinx (>=6.0)", "myst-parser (>=2.0.0)", "sphinx_rtd_theme (>=1.1.0)"]
-optional = ["python-socks", "wsaccel"]
-test = ["pytest", "websockets"]
-
-[[package]]
-name = "websockets"
-version = "15.0.1"
-description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
-optional = false
-python-versions = ">=3.9"
-groups = ["main"]
-files = [
- {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b"},
- {file = "websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205"},
- {file = "websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a"},
- {file = "websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e"},
- {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf"},
- {file = "websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb"},
- {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d"},
- {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9"},
- {file = "websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c"},
- {file = "websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256"},
- {file = "websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41"},
- {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431"},
- {file = "websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57"},
- {file = "websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905"},
- {file = "websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562"},
- {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792"},
- {file = "websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413"},
- {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8"},
- {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3"},
- {file = "websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf"},
- {file = "websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85"},
- {file = "websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065"},
- {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3"},
- {file = "websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665"},
- {file = "websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2"},
- {file = "websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215"},
- {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5"},
- {file = "websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65"},
- {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe"},
- {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4"},
- {file = "websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597"},
- {file = "websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9"},
- {file = "websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7"},
- {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931"},
- {file = "websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675"},
- {file = "websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151"},
- {file = "websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22"},
- {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f"},
- {file = "websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8"},
- {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375"},
- {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d"},
- {file = "websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4"},
- {file = "websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa"},
- {file = "websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561"},
- {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5"},
- {file = "websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a"},
- {file = "websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b"},
- {file = "websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770"},
- {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb"},
- {file = "websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054"},
- {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee"},
- {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed"},
- {file = "websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880"},
- {file = "websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411"},
- {file = "websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04"},
- {file = "websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f"},
- {file = "websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123"},
- {file = "websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f"},
- {file = "websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee"},
-]
-
-[[package]]
-name = "werkzeug"
-version = "3.1.5"
-description = "The comprehensive WSGI web application library."
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "test"]
-files = [
- {file = "werkzeug-3.1.5-py3-none-any.whl", hash = "sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc"},
- {file = "werkzeug-3.1.5.tar.gz", hash = "sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67"},
-]
-
-[package.dependencies]
-markupsafe = ">=2.1.1"
-
-[package.extras]
-watchdog = ["watchdog (>=2.3)"]
-
-[[package]]
-name = "wheel"
-version = "0.46.3"
-description = "Command line tool for manipulating wheel files"
-optional = false
-python-versions = ">=3.9"
-groups = ["dev"]
-files = [
- {file = "wheel-0.46.3-py3-none-any.whl", hash = "sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d"},
- {file = "wheel-0.46.3.tar.gz", hash = "sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803"},
-]
-
-[package.dependencies]
-packaging = ">=24.0"
-
-[package.extras]
-test = ["pytest (>=6.0.0)", "setuptools (>=77)"]
-
-[[package]]
-name = "wrapt"
-version = "1.17.3"
-description = "Module for decorators, wrappers and monkey patching."
-optional = false
-python-versions = ">=3.8"
-groups = ["main"]
-files = [
- {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04"},
- {file = "wrapt-1.17.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2"},
- {file = "wrapt-1.17.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c"},
- {file = "wrapt-1.17.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775"},
- {file = "wrapt-1.17.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd"},
- {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05"},
- {file = "wrapt-1.17.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418"},
- {file = "wrapt-1.17.3-cp310-cp310-win32.whl", hash = "sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390"},
- {file = "wrapt-1.17.3-cp310-cp310-win_amd64.whl", hash = "sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6"},
- {file = "wrapt-1.17.3-cp310-cp310-win_arm64.whl", hash = "sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18"},
- {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"},
- {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"},
- {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"},
- {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"},
- {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"},
- {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"},
- {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"},
- {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"},
- {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"},
- {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"},
- {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"},
- {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"},
- {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"},
- {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"},
- {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"},
- {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"},
- {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"},
- {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"},
- {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"},
- {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"},
- {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0"},
- {file = "wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77"},
- {file = "wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7"},
- {file = "wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277"},
- {file = "wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d"},
- {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa"},
- {file = "wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050"},
- {file = "wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8"},
- {file = "wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb"},
- {file = "wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16"},
- {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39"},
- {file = "wrapt-1.17.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235"},
- {file = "wrapt-1.17.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c"},
- {file = "wrapt-1.17.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b"},
- {file = "wrapt-1.17.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa"},
- {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7"},
- {file = "wrapt-1.17.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4"},
- {file = "wrapt-1.17.3-cp314-cp314-win32.whl", hash = "sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10"},
- {file = "wrapt-1.17.3-cp314-cp314-win_amd64.whl", hash = "sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6"},
- {file = "wrapt-1.17.3-cp314-cp314-win_arm64.whl", hash = "sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58"},
- {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a"},
- {file = "wrapt-1.17.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067"},
- {file = "wrapt-1.17.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454"},
- {file = "wrapt-1.17.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e"},
- {file = "wrapt-1.17.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f"},
- {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056"},
- {file = "wrapt-1.17.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804"},
- {file = "wrapt-1.17.3-cp314-cp314t-win32.whl", hash = "sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977"},
- {file = "wrapt-1.17.3-cp314-cp314t-win_amd64.whl", hash = "sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116"},
- {file = "wrapt-1.17.3-cp314-cp314t-win_arm64.whl", hash = "sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6"},
- {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225"},
- {file = "wrapt-1.17.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a"},
- {file = "wrapt-1.17.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f"},
- {file = "wrapt-1.17.3-cp38-cp38-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00"},
- {file = "wrapt-1.17.3-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56"},
- {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5"},
- {file = "wrapt-1.17.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22"},
- {file = "wrapt-1.17.3-cp38-cp38-win32.whl", hash = "sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c"},
- {file = "wrapt-1.17.3-cp38-cp38-win_amd64.whl", hash = "sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2"},
- {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc"},
- {file = "wrapt-1.17.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9"},
- {file = "wrapt-1.17.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d"},
- {file = "wrapt-1.17.3-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a"},
- {file = "wrapt-1.17.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139"},
- {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df"},
- {file = "wrapt-1.17.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b"},
- {file = "wrapt-1.17.3-cp39-cp39-win32.whl", hash = "sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81"},
- {file = "wrapt-1.17.3-cp39-cp39-win_amd64.whl", hash = "sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f"},
- {file = "wrapt-1.17.3-cp39-cp39-win_arm64.whl", hash = "sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f"},
- {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"},
- {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"},
-]
-
-[[package]]
-name = "wsproto"
-version = "1.3.1"
-description = "Pure-Python WebSocket protocol implementation"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "wsproto-1.3.1-py3-none-any.whl", hash = "sha256:297ce79322989c0d286cc158681641cd18bc7632dfb38cf4054696a89179b993"},
- {file = "wsproto-1.3.1.tar.gz", hash = "sha256:81529992325c28f0d9b86ca66fc973da96eb80ab53410249ce2e502749c7723c"},
-]
-
-[package.dependencies]
-h11 = ">=0.16.0,<1"
-
-[[package]]
-name = "xxhash"
-version = "3.6.0"
-description = "Python binding for xxHash"
-optional = false
-python-versions = ">=3.7"
-groups = ["dev"]
-files = [
- {file = "xxhash-3.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71"},
- {file = "xxhash-3.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d"},
- {file = "xxhash-3.6.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8"},
- {file = "xxhash-3.6.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058"},
- {file = "xxhash-3.6.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2"},
- {file = "xxhash-3.6.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc"},
- {file = "xxhash-3.6.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc"},
- {file = "xxhash-3.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07"},
- {file = "xxhash-3.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4"},
- {file = "xxhash-3.6.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06"},
- {file = "xxhash-3.6.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4"},
- {file = "xxhash-3.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b"},
- {file = "xxhash-3.6.0-cp310-cp310-win32.whl", hash = "sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b"},
- {file = "xxhash-3.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb"},
- {file = "xxhash-3.6.0-cp310-cp310-win_arm64.whl", hash = "sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d"},
- {file = "xxhash-3.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a"},
- {file = "xxhash-3.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa"},
- {file = "xxhash-3.6.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248"},
- {file = "xxhash-3.6.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62"},
- {file = "xxhash-3.6.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f"},
- {file = "xxhash-3.6.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e"},
- {file = "xxhash-3.6.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8"},
- {file = "xxhash-3.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0"},
- {file = "xxhash-3.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77"},
- {file = "xxhash-3.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c"},
- {file = "xxhash-3.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b"},
- {file = "xxhash-3.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3"},
- {file = "xxhash-3.6.0-cp311-cp311-win32.whl", hash = "sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd"},
- {file = "xxhash-3.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef"},
- {file = "xxhash-3.6.0-cp311-cp311-win_arm64.whl", hash = "sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7"},
- {file = "xxhash-3.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c"},
- {file = "xxhash-3.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204"},
- {file = "xxhash-3.6.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490"},
- {file = "xxhash-3.6.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2"},
- {file = "xxhash-3.6.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa"},
- {file = "xxhash-3.6.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0"},
- {file = "xxhash-3.6.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2"},
- {file = "xxhash-3.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9"},
- {file = "xxhash-3.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e"},
- {file = "xxhash-3.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374"},
- {file = "xxhash-3.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d"},
- {file = "xxhash-3.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae"},
- {file = "xxhash-3.6.0-cp312-cp312-win32.whl", hash = "sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb"},
- {file = "xxhash-3.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c"},
- {file = "xxhash-3.6.0-cp312-cp312-win_arm64.whl", hash = "sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829"},
- {file = "xxhash-3.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec"},
- {file = "xxhash-3.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1"},
- {file = "xxhash-3.6.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6"},
- {file = "xxhash-3.6.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263"},
- {file = "xxhash-3.6.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546"},
- {file = "xxhash-3.6.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89"},
- {file = "xxhash-3.6.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d"},
- {file = "xxhash-3.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7"},
- {file = "xxhash-3.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db"},
- {file = "xxhash-3.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42"},
- {file = "xxhash-3.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11"},
- {file = "xxhash-3.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd"},
- {file = "xxhash-3.6.0-cp313-cp313-win32.whl", hash = "sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799"},
- {file = "xxhash-3.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392"},
- {file = "xxhash-3.6.0-cp313-cp313-win_arm64.whl", hash = "sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6"},
- {file = "xxhash-3.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702"},
- {file = "xxhash-3.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db"},
- {file = "xxhash-3.6.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54"},
- {file = "xxhash-3.6.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f"},
- {file = "xxhash-3.6.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5"},
- {file = "xxhash-3.6.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1"},
- {file = "xxhash-3.6.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee"},
- {file = "xxhash-3.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd"},
- {file = "xxhash-3.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729"},
- {file = "xxhash-3.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292"},
- {file = "xxhash-3.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf"},
- {file = "xxhash-3.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033"},
- {file = "xxhash-3.6.0-cp313-cp313t-win32.whl", hash = "sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec"},
- {file = "xxhash-3.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8"},
- {file = "xxhash-3.6.0-cp313-cp313t-win_arm64.whl", hash = "sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746"},
- {file = "xxhash-3.6.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e"},
- {file = "xxhash-3.6.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405"},
- {file = "xxhash-3.6.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3"},
- {file = "xxhash-3.6.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6"},
- {file = "xxhash-3.6.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063"},
- {file = "xxhash-3.6.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7"},
- {file = "xxhash-3.6.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b"},
- {file = "xxhash-3.6.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd"},
- {file = "xxhash-3.6.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0"},
- {file = "xxhash-3.6.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152"},
- {file = "xxhash-3.6.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11"},
- {file = "xxhash-3.6.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5"},
- {file = "xxhash-3.6.0-cp314-cp314-win32.whl", hash = "sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f"},
- {file = "xxhash-3.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad"},
- {file = "xxhash-3.6.0-cp314-cp314-win_arm64.whl", hash = "sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679"},
- {file = "xxhash-3.6.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4"},
- {file = "xxhash-3.6.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67"},
- {file = "xxhash-3.6.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad"},
- {file = "xxhash-3.6.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b"},
- {file = "xxhash-3.6.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b"},
- {file = "xxhash-3.6.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca"},
- {file = "xxhash-3.6.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a"},
- {file = "xxhash-3.6.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99"},
- {file = "xxhash-3.6.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3"},
- {file = "xxhash-3.6.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6"},
- {file = "xxhash-3.6.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93"},
- {file = "xxhash-3.6.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518"},
- {file = "xxhash-3.6.0-cp314-cp314t-win32.whl", hash = "sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119"},
- {file = "xxhash-3.6.0-cp314-cp314t-win_amd64.whl", hash = "sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f"},
- {file = "xxhash-3.6.0-cp314-cp314t-win_arm64.whl", hash = "sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95"},
- {file = "xxhash-3.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41"},
- {file = "xxhash-3.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8"},
- {file = "xxhash-3.6.0-cp38-cp38-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e"},
- {file = "xxhash-3.6.0-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850"},
- {file = "xxhash-3.6.0-cp38-cp38-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa"},
- {file = "xxhash-3.6.0-cp38-cp38-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788"},
- {file = "xxhash-3.6.0-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df"},
- {file = "xxhash-3.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1"},
- {file = "xxhash-3.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65"},
- {file = "xxhash-3.6.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87"},
- {file = "xxhash-3.6.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f"},
- {file = "xxhash-3.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b"},
- {file = "xxhash-3.6.0-cp38-cp38-win32.whl", hash = "sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536"},
- {file = "xxhash-3.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004"},
- {file = "xxhash-3.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a"},
- {file = "xxhash-3.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7"},
- {file = "xxhash-3.6.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2"},
- {file = "xxhash-3.6.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d"},
- {file = "xxhash-3.6.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec"},
- {file = "xxhash-3.6.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222"},
- {file = "xxhash-3.6.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919"},
- {file = "xxhash-3.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6"},
- {file = "xxhash-3.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360"},
- {file = "xxhash-3.6.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4"},
- {file = "xxhash-3.6.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86"},
- {file = "xxhash-3.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796"},
- {file = "xxhash-3.6.0-cp39-cp39-win32.whl", hash = "sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d"},
- {file = "xxhash-3.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802"},
- {file = "xxhash-3.6.0-cp39-cp39-win_arm64.whl", hash = "sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6"},
- {file = "xxhash-3.6.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0"},
- {file = "xxhash-3.6.0-pp311-pypy311_pp73-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296"},
- {file = "xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13"},
- {file = "xxhash-3.6.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd"},
- {file = "xxhash-3.6.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d"},
- {file = "xxhash-3.6.0.tar.gz", hash = "sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6"},
-]
-
-[[package]]
-name = "yarl"
-version = "1.22.0"
-description = "Yet another URL library"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev", "test"]
-files = [
- {file = "yarl-1.22.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e"},
- {file = "yarl-1.22.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f"},
- {file = "yarl-1.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf"},
- {file = "yarl-1.22.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a"},
- {file = "yarl-1.22.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c"},
- {file = "yarl-1.22.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147"},
- {file = "yarl-1.22.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb"},
- {file = "yarl-1.22.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6"},
- {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0"},
- {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda"},
- {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc"},
- {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737"},
- {file = "yarl-1.22.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467"},
- {file = "yarl-1.22.0-cp310-cp310-win32.whl", hash = "sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea"},
- {file = "yarl-1.22.0-cp310-cp310-win_amd64.whl", hash = "sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca"},
- {file = "yarl-1.22.0-cp310-cp310-win_arm64.whl", hash = "sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b"},
- {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511"},
- {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6"},
- {file = "yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028"},
- {file = "yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d"},
- {file = "yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503"},
- {file = "yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65"},
- {file = "yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e"},
- {file = "yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d"},
- {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7"},
- {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967"},
- {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed"},
- {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6"},
- {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e"},
- {file = "yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca"},
- {file = "yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b"},
- {file = "yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376"},
- {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f"},
- {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2"},
- {file = "yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74"},
- {file = "yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df"},
- {file = "yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb"},
- {file = "yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2"},
- {file = "yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82"},
- {file = "yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a"},
- {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124"},
- {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa"},
- {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7"},
- {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d"},
- {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520"},
- {file = "yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8"},
- {file = "yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c"},
- {file = "yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74"},
- {file = "yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53"},
- {file = "yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a"},
- {file = "yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c"},
- {file = "yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601"},
- {file = "yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a"},
- {file = "yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df"},
- {file = "yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2"},
- {file = "yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b"},
- {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273"},
- {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a"},
- {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d"},
- {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02"},
- {file = "yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67"},
- {file = "yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95"},
- {file = "yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d"},
- {file = "yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b"},
- {file = "yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10"},
- {file = "yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3"},
- {file = "yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9"},
- {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f"},
- {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0"},
- {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e"},
- {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708"},
- {file = "yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f"},
- {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d"},
- {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8"},
- {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5"},
- {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f"},
- {file = "yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62"},
- {file = "yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03"},
- {file = "yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249"},
- {file = "yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b"},
- {file = "yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4"},
- {file = "yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683"},
- {file = "yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b"},
- {file = "yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e"},
- {file = "yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590"},
- {file = "yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2"},
- {file = "yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da"},
- {file = "yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784"},
- {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b"},
- {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694"},
- {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d"},
- {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd"},
- {file = "yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da"},
- {file = "yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2"},
- {file = "yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79"},
- {file = "yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33"},
- {file = "yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1"},
- {file = "yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca"},
- {file = "yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53"},
- {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c"},
- {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf"},
- {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face"},
- {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b"},
- {file = "yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486"},
- {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138"},
- {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a"},
- {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529"},
- {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093"},
- {file = "yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c"},
- {file = "yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e"},
- {file = "yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27"},
- {file = "yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1"},
- {file = "yarl-1.22.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748"},
- {file = "yarl-1.22.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859"},
- {file = "yarl-1.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9"},
- {file = "yarl-1.22.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054"},
- {file = "yarl-1.22.0-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b"},
- {file = "yarl-1.22.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60"},
- {file = "yarl-1.22.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890"},
- {file = "yarl-1.22.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba"},
- {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca"},
- {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba"},
- {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b"},
- {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e"},
- {file = "yarl-1.22.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8"},
- {file = "yarl-1.22.0-cp39-cp39-win32.whl", hash = "sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b"},
- {file = "yarl-1.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed"},
- {file = "yarl-1.22.0-cp39-cp39-win_arm64.whl", hash = "sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2"},
- {file = "yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff"},
- {file = "yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71"},
-]
-
-[package.dependencies]
-idna = ">=2.0"
-multidict = ">=4.0"
-propcache = ">=0.2.1"
-
-[[package]]
-name = "zipp"
-version = "3.23.0"
-description = "Backport of pathlib-compatible object wrapper for zip files"
-optional = false
-python-versions = ">=3.9"
-groups = ["main", "dev"]
-files = [
- {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"},
- {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"},
-]
-
-[package.extras]
-check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""]
-cover = ["pytest-cov"]
-doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
-enabler = ["pytest-enabler (>=2.2)"]
-test = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more_itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"]
-type = ["pytest-mypy"]
-
-[[package]]
-name = "zope-event"
-version = "6.1"
-description = "Very basic event publishing system"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "zope_event-6.1-py3-none-any.whl", hash = "sha256:0ca78b6391b694272b23ec1335c0294cc471065ed10f7f606858fc54566c25a0"},
- {file = "zope_event-6.1.tar.gz", hash = "sha256:6052a3e0cb8565d3d4ef1a3a7809336ac519bc4fe38398cb8d466db09adef4f0"},
-]
-
-[package.extras]
-docs = ["Sphinx"]
-test = ["zope.testrunner (>=6.4)"]
-
-[[package]]
-name = "zope-interface"
-version = "8.1"
-description = "Interfaces for Python"
-optional = false
-python-versions = ">=3.10"
-groups = ["test"]
-files = [
- {file = "zope_interface-8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b6370bc29799223e9a4756e89f358cbfba8e4112fc5046403c849bcc52f1ff32"},
- {file = "zope_interface-8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:638e83a5c15a337e52d36620478d49dbf206a46d34bcc75ff03211e94b12267d"},
- {file = "zope_interface-8.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b88e0516bc7f3979839f44adfdbfa8a57d81154a161cbd64642ace22892969af"},
- {file = "zope_interface-8.1-cp310-cp310-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3c17d683a11cf09eebf332e4771fc2973c15f8428a9a4fc478b39a422f32157b"},
- {file = "zope_interface-8.1-cp310-cp310-win_amd64.whl", hash = "sha256:e826eeda579fcee2624eea6014877103ca7510bd1353bfae1d64e1cabd691d35"},
- {file = "zope_interface-8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:db263a60c728c86e6a74945f3f74cfe0ede252e726cf71e05a0c7aca8d9d5432"},
- {file = "zope_interface-8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cfa89e5b05b7a79ab34e368293ad008321231e321b3ce4430487407b4fe3450a"},
- {file = "zope_interface-8.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:87eaf011912a06ef86da70aba2ca0ddb68b8ab84a7d1da6b144a586b70a61bca"},
- {file = "zope_interface-8.1-cp311-cp311-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10f06d128f1c181ded3af08c5004abcb3719c13a976ce9163124e7eeded6899a"},
- {file = "zope_interface-8.1-cp311-cp311-win_amd64.whl", hash = "sha256:17fb5382a4b9bd2ea05648a457c583e5a69f0bfa3076ed1963d48bc42a2da81f"},
- {file = "zope_interface-8.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8aee385282ab2a9813171b15f41317e22ab0a96cf05e9e9e16b29f4af8b6feb"},
- {file = "zope_interface-8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af651a87f950a13e45fd49510111f582717fb106a63d6a0c2d3ba86b29734f07"},
- {file = "zope_interface-8.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:80ed7683cf337f3b295e4b96153e2e87f12595c218323dc237c0147a6cc9da26"},
- {file = "zope_interface-8.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb9a7a45944b28c16d25df7a91bf2b9bdb919fa2b9e11782366a1e737d266ec1"},
- {file = "zope_interface-8.1-cp312-cp312-win_amd64.whl", hash = "sha256:fc5e120e3618741714c474b2427d08d36bd292855208b4397e325bd50d81439d"},
- {file = "zope_interface-8.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:afc2bbd1c5d9ecda8c2114a2793bda811ea175742c93dc77a02d5ed49c7a732e"},
- {file = "zope_interface-8.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:827a9ad0ebfef467f047d17d83868f66eb44feb00daf2e3dbd404b6f1cb08858"},
- {file = "zope_interface-8.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:3913ad3fced813c4af551aae4511dc000c6d4df648430060593aec851bb5fc19"},
- {file = "zope_interface-8.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c073ba91caeff93aaf9569c9c3ec3fd790290329cefa69eb6dcb43eabb832c2c"},
- {file = "zope_interface-8.1-cp313-cp313-win_amd64.whl", hash = "sha256:eef72e1726fa055510c1442c3bc3614a4fd0cd056e26c824c26a27d02ad9cfdd"},
- {file = "zope_interface-8.1-cp314-cp314-macosx_10_9_x86_64.whl", hash = "sha256:04ee726e6939be1c2924d8513a17eb819217129e25d3217ca009cf9c8832e3fe"},
- {file = "zope_interface-8.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b931e7241d089df18e0e34a7bfba019bc89c5bf49af8894b4540a0857cb70b79"},
- {file = "zope_interface-8.1-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:c09a4a25007f113c82fcdf4b40ffcbcfaa3f26e428d9cbb9ea322fe27149bc39"},
- {file = "zope_interface-8.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:26c515e2f92da839d531ef86a3bbaafc3f22bd9aea5eb0c1dc397f67abff56d7"},
- {file = "zope_interface-8.1-cp314-cp314-win_amd64.whl", hash = "sha256:76dfe5580cac661b0aad5f0d308c09d25b567c908a1695bd68986507fd61b61d"},
- {file = "zope_interface-8.1.tar.gz", hash = "sha256:a02ee40770c6a2f3d168a8f71f09b62aec3e4fb366da83f8e849dbaa5b38d12f"},
-]
-
-[package.extras]
-docs = ["Sphinx", "furo", "repoze.sphinx.autointerface"]
-test = ["coverage[toml]", "zope.event", "zope.testing"]
-testing = ["coverage[toml]", "zope.event", "zope.testing"]
-
-[metadata]
-lock-version = "2.1"
-python-versions = ">=3.12.*, <3.13"
-content-hash = "4cf6ad98bfc7c2b84ead5a59aef14b526572cb8744805fd6b268567db99ab22d"
diff --git a/wren-ai-service/pyproject.toml b/wren-ai-service/pyproject.toml
deleted file mode 100644
index 0210cfe20..000000000
--- a/wren-ai-service/pyproject.toml
+++ /dev/null
@@ -1,80 +0,0 @@
-[tool.poetry]
-name = "wren-ai-service"
-version = "0.29.3"
-description = ""
-authors = ["dev@getwren.ai"]
-license = "AGPL-3.0"
-readme = "README.md"
-package-mode = false
-
-[tool.poetry.dependencies]
-python = ">=3.12.*, <3.13"
-fastapi = "^0.121.1"
-uvicorn = {extras = ["standard"], version = "^0.29.0"} # Litellm requires uvicorn < 0.30.0
-python-dotenv = "^1.0.1"
-haystack-ai = "==2.7.0"
-openai = "^2.8.0"
-qdrant-haystack = "^7.0.0"
-backoff = "^2.2.1"
-tqdm = "^4.66.4"
-numpy = "^1.26.4"
-sqlparse = "^0.5.4"
-orjson = "^3.11.5"
-sf-hamilton = {version = "^1.69.0"}
-aiohttp = {extras = ["speedups"], version = "^3.13.3"}
-ollama-haystack = "^2.0.0"
-langfuse = "^2.43.3"
-ollama = "^0.4.0"
-toml = "^0.10.2"
-cachetools = "^5.5.0"
-pyyaml = "^6.0.2"
-pydantic-settings = "^2.5.2"
-google-auth = "^2.35.0"
-tiktoken = "^0.12.0"
-jsonschema = "^4.23.0"
-litellm = "^1.83.7"
-boto3 = "^1.34.34" # Litellm requires boto3 = 1.34.34
-qdrant-client = "==1.15.0"
-filelock = "^3.20.1"
-urllib3 = ">=2.6.3"
-werkzeug = ">=3.1.5" # CVE: safe_join Windows device name vulnerability
-marshmallow = ">=3.26.2" # CVE: Schema.load(many=True) DoS
-pillow = ">=12.1.1" # CVE: out-of-bounds write when loading PSD images
-protobuf = ">=5.29.6"
-
-[tool.poetry.group.dev.dependencies]
-pre-commit = "^3.7.1"
-streamlit = "^1.37.0"
-watchdog = "^4.0.0"
-pandas = "^2.2.2"
-matplotlib = "^3.9.2"
-sseclient-py = "^1.8.0"
-dspy-ai = "^2.5.26"
-requests = "^2.32.4"
-extra-streamlit-components = "^0.1.71"
-deepeval = "^3.0.0"
-tomlkit = "^0.13.0"
-nltk = "^3.9.3"
-psycopg2 = "^2.9.10"
-
-[tool.poetry.group.eval.dependencies]
-gitpython = "^3.1.43"
-plotly = "^5.24.1"
-nbformat = "^5.1.3"
-ipykernel = "^6.29.5"
-itables = "^2.2.1"
-gdown = "^5.2.0"
-streamlit-tags = "^1.2.8"
-docker = "^7.1.0"
-
-[tool.poetry.group.test.dependencies]
-locust = "^2.32.0"
-pytest = "^8.3.0"
-pytest-cov = "^6.0.0"
-pytest-asyncio = "^0.24.0"
-aioresponses = "^0.7.0"
-pytest-mock = "^3.14.0"
-
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
diff --git a/wren-ai-service/ruff.toml b/wren-ai-service/ruff.toml
deleted file mode 100644
index b365289b9..000000000
--- a/wren-ai-service/ruff.toml
+++ /dev/null
@@ -1,77 +0,0 @@
-# Exclude a variety of commonly ignored directories.
-exclude = [
- ".bzr",
- ".direnv",
- ".eggs",
- ".git",
- ".git-rewrite",
- ".hg",
- ".ipynb_checkpoints",
- ".mypy_cache",
- ".nox",
- ".pants.d",
- ".pyenv",
- ".pytest_cache",
- ".pytype",
- ".ruff_cache",
- ".svn",
- ".tox",
- ".venv",
- ".vscode",
- "__pypackages__",
- "_build",
- "buck-out",
- "build",
- "dist",
- "node_modules",
- "site-packages",
- "venv",
-]
-
-# Same as Black.
-line-length = 88
-indent-width = 4
-
-# Assume Python 3.8
-target-version = "py38"
-
-[lint]
-# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
-# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
-# McCabe complexity (`C901`) by default.
-select = ["E4", "E7", "E9", "F", "I001"]
-ignore = []
-
-# Allow fix for all enabled rules (when `--fix`) is provided.
-fixable = ["ALL"]
-unfixable = []
-
-# Allow unused variables when underscore-prefixed.
-dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
-
-[format]
-# Like Black, use double quotes for strings.
-quote-style = "double"
-
-# Like Black, indent with spaces, rather than tabs.
-indent-style = "space"
-
-# Like Black, respect magic trailing commas.
-skip-magic-trailing-comma = false
-
-# Like Black, automatically detect the appropriate line ending.
-line-ending = "auto"
-
-# Enable auto-formatting of code examples in docstrings. Markdown,
-# reStructuredText code/literal blocks and doctests are all supported.
-#
-# This is currently disabled by default, but it is planned for this
-# to be opt-out in the future.
-docstring-code-format = false
-
-# Set the line length limit used when formatting code snippets in
-# docstrings.
-#
-# This only has an effect when the `docstring-code-format` setting is
-# enabled.
-docstring-code-line-length = "dynamic"
diff --git a/wren-ai-service/src/__init__.py b/wren-ai-service/src/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/wren-ai-service/src/__main__.py b/wren-ai-service/src/__main__.py
deleted file mode 100644
index de141c3fd..000000000
--- a/wren-ai-service/src/__main__.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from contextlib import asynccontextmanager
-
-import uvicorn
-from fastapi import FastAPI
-from fastapi.exceptions import RequestValidationError
-from fastapi.middleware.cors import CORSMiddleware
-from fastapi.responses import ORJSONResponse, RedirectResponse
-from langfuse.decorators import langfuse_context
-
-from src.config import settings
-from src.globals import (
- create_service_container,
- create_service_metadata,
-)
-from src.providers import generate_components
-from src.utils import (
- init_langfuse,
- setup_custom_logger,
-)
-from src.web.v1 import routers
-
-setup_custom_logger(
- "wren-ai-service", level_str=settings.logging_level, is_dev=settings.development
-)
-
-
-# https://fastapi.tiangolo.com/advanced/events/#lifespan
-@asynccontextmanager
-async def lifespan(app: FastAPI):
- # startup events
- pipe_components = generate_components(settings.components)
- app.state.service_container = create_service_container(pipe_components, settings)
- app.state.service_metadata = create_service_metadata(pipe_components)
- init_langfuse(settings)
-
- yield
-
- # shutdown events
- langfuse_context.flush()
-
-
-app = FastAPI(
- title="wren-ai-service API Docs",
- lifespan=lifespan,
- redoc_url=None,
- default_response_class=ORJSONResponse,
-)
-
-app.add_middleware(
- CORSMiddleware,
- allow_origins=["*"],
- allow_credentials=True,
- allow_methods=["*"],
- allow_headers=["*"],
-)
-app.include_router(routers.router, prefix="/v1", tags=["v1"])
-if settings.development:
- from src.web import development
-
- app.include_router(development.router, prefix="/dev", tags=["dev"])
-
-
-@app.exception_handler(Exception)
-async def exception_handler(_, exc: Exception):
- return ORJSONResponse(
- status_code=500,
- content={"detail": str(exc)},
- )
-
-
-@app.exception_handler(RequestValidationError)
-async def request_exception_handler(_, exc: Exception):
- return ORJSONResponse(
- status_code=400,
- content={"detail": str(exc)},
- )
-
-
-@app.get("/")
-def root():
- return RedirectResponse(url="/docs")
-
-
-@app.get("/health")
-def health():
- return {"status": "ok"}
-
-
-if __name__ == "__main__":
- uvicorn.run(
- "src.__main__:app",
- host=settings.host,
- port=settings.port,
- reload=settings.development,
- reload_includes=["src/**/*.py", ".env.dev", "config.yaml"],
- reload_excludes=["tests/**/*.py", "eval/**/*.py"],
- workers=1,
- loop="uvloop",
- http="httptools",
- )
diff --git a/wren-ai-service/src/config.py b/wren-ai-service/src/config.py
deleted file mode 100644
index c5acf4ae4..000000000
--- a/wren-ai-service/src/config.py
+++ /dev/null
@@ -1,121 +0,0 @@
-import logging
-
-import yaml
-from dotenv import load_dotenv
-from pydantic import Field
-from pydantic_settings import BaseSettings
-
-logger = logging.getLogger("wren-ai-service")
-
-
-class Settings(BaseSettings):
- """
- Configuration settings for the Wren AI service.
-
- The settings are loaded in the following order of precedence:
- 1. Default values: Defined in the class attributes.
- 2. Environment variables: Overrides default values if set.
- 3. .env.dev file: Loads additional settings or overrides previous ones.
- 4. config.yaml file: Provides the highest priority configuration.
-
- This hierarchical loading allows for flexible configuration management
- across different environments and deployment scenarios.
- """
-
- host: str = Field(default="127.0.0.1", alias="WREN_AI_SERVICE_HOST")
- port: int = Field(default=5555, alias="WREN_AI_SERVICE_PORT")
-
- # indexing and retrieval config
- column_indexing_batch_size: int = Field(default=50)
- table_retrieval_size: int = Field(default=10)
- table_column_retrieval_size: int = Field(default=100)
- enable_column_pruning: bool = Field(default=False)
- historical_question_retrieval_similarity_threshold: float = Field(default=0.9)
- sql_pairs_similarity_threshold: float = Field(default=0.7)
- sql_pairs_retrieval_max_size: int = Field(default=10)
- instructions_similarity_threshold: float = Field(default=0.7)
- instructions_top_k: int = Field(default=10)
-
- # generation config
- allow_intent_classification: bool = Field(default=True)
- allow_sql_generation_reasoning: bool = Field(default=True)
- allow_sql_functions_retrieval: bool = Field(default=True)
- allow_sql_diagnosis: bool = Field(default=True)
- allow_sql_knowledge_retrieval: bool = Field(default=False)
- max_histories: int = Field(default=5)
- max_sql_correction_retries: int = Field(default=3)
-
- # engine config
- engine_timeout: float = Field(default=30.0)
-
- # service config
- query_cache_ttl: int = Field(default=3600) # unit: seconds
- query_cache_maxsize: int = Field(
- default=1_000_000,
- comment="""
- the maxsize is a necessary parameter to init cache, but we don't want to expose it to the user
- so we set it to 1_000_000, which is a large number
- """,
- )
-
- # user guide config
- is_oss: bool = Field(default=True)
- doc_endpoint: str = Field(default="https://docs.getwren.ai")
-
- # langfuse config
- # in order to use langfuse, we also need to set the LANGFUSE_SECRET_KEY and LANGFUSE_PUBLIC_KEY in the .env or .env.dev file
- langfuse_host: str = Field(default="https://cloud.langfuse.com")
- langfuse_enable: bool = Field(default=True)
-
- # debug config
- logging_level: str = Field(default="INFO")
- development: bool = Field(default=False)
-
- # this is used to store the config like type: llm, embedder, etc. and we will process them later
- config_path: str = Field(default="config.yaml")
- _components: list[dict]
-
- sql_pairs_path: str = Field(default="sql_pairs.json")
-
- def __init__(self):
- load_dotenv(".env.dev", override=True)
- super().__init__()
- raw = self.config_loader()
- self.override(raw)
- self._components = [
- component for component in raw if "settings" not in component
- ]
-
- def config_loader(self):
- try:
- with open(self.config_path, "r") as file:
- return list(yaml.load_all(file, Loader=yaml.SafeLoader))
- except FileNotFoundError:
- message = f"Warning: Configuration file {self.config_path} not found. Using default settings."
- logger.warning(message)
- return []
- except yaml.YAMLError as e:
- logger.exception(f"Error parsing YAML file: {e}")
- return []
-
- def override(self, raw: list[dict]) -> None:
- override_settings = {}
-
- for doc in raw:
- if "settings" in doc:
- override_settings = doc["settings"]
- break
-
- for key, value in override_settings.items():
- if hasattr(self, key):
- setattr(self, key, value)
- else:
- message = f"Warning: Unknown configuration key '{key}' in YAML file."
- logger.warning(message)
-
- @property
- def components(self) -> list[dict]:
- return self._components
-
-
-settings = Settings()
diff --git a/wren-ai-service/src/core/__init__.py b/wren-ai-service/src/core/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/wren-ai-service/src/core/engine.py b/wren-ai-service/src/core/engine.py
deleted file mode 100644
index 163135e02..000000000
--- a/wren-ai-service/src/core/engine.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import logging
-import re
-from abc import ABCMeta, abstractmethod
-from typing import Any, Dict, Optional, Tuple
-
-import aiohttp
-from pydantic import BaseModel
-
-logger = logging.getLogger("wren-ai-service")
-
-
-class EngineConfig(BaseModel):
- provider: str = "wren_ui"
- config: dict = {}
-
-
-class Engine(metaclass=ABCMeta):
- @abstractmethod
- async def execute_sql(
- self,
- sql: str,
- session: aiohttp.ClientSession,
- dry_run: bool = True,
- **kwargs,
- ) -> Tuple[bool, Optional[Dict[str, Any]]]:
- ...
-
-
-def clean_generation_result(result: str) -> str:
- def _normalize_whitespace(s: str) -> str:
- return re.sub(r"\s+", " ", s).strip()
-
- return (
- _normalize_whitespace(result)
- .replace("```sql", "")
- .replace("```json", "")
- .replace('"""', "")
- .replace("'''", "")
- .replace("```", "")
- .replace(";", "")
- )
-
-
-def remove_limit_statement(sql: str) -> str:
- pattern = r"\s*LIMIT\s+\d+(\s*;?\s*--.*|\s*;?\s*)$"
- modified_sql = re.sub(pattern, "", sql, flags=re.IGNORECASE)
-
- return modified_sql
diff --git a/wren-ai-service/src/core/pipeline.py b/wren-ai-service/src/core/pipeline.py
deleted file mode 100644
index 02a477845..000000000
--- a/wren-ai-service/src/core/pipeline.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from abc import ABCMeta, abstractmethod
-from collections.abc import Mapping
-from dataclasses import dataclass
-from typing import Any, Dict
-
-from hamilton.async_driver import AsyncDriver
-from hamilton.driver import Driver
-from haystack import Pipeline
-
-from src.core.engine import Engine
-from src.core.provider import DocumentStoreProvider, EmbedderProvider, LLMProvider
-
-
-class BasicPipeline(metaclass=ABCMeta):
- def __init__(self, pipe: Pipeline | AsyncDriver | Driver):
- self._pipe = pipe
-
- @abstractmethod
- def run(self, *args, **kwargs) -> Dict[str, Any]:
- ...
-
-
-@dataclass
-class PipelineComponent(Mapping):
- llm_provider: LLMProvider = None
- embedder_provider: EmbedderProvider = None
- document_store_provider: DocumentStoreProvider = None
- engine: Engine = None
-
- def __getitem__(self, key):
- return getattr(self, key)
-
- def __iter__(self):
- return iter(self.__dict__)
-
- def __len__(self):
- return len(self.__dict__)
diff --git a/wren-ai-service/src/core/provider.py b/wren-ai-service/src/core/provider.py
deleted file mode 100644
index 4246dd490..000000000
--- a/wren-ai-service/src/core/provider.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from abc import ABCMeta, abstractmethod
-
-from haystack.document_stores.types import DocumentStore
-
-
-class LLMProvider(metaclass=ABCMeta):
- @abstractmethod
- def get_generator(self, *args, **kwargs):
- ...
-
- def get_model(self):
- return self._model
-
- def get_model_kwargs(self):
- return self._model_kwargs
-
- def get_context_window_size(self):
- return self._context_window_size
-
-
-class EmbedderProvider(metaclass=ABCMeta):
- @abstractmethod
- def get_text_embedder(self, *args, **kwargs):
- ...
-
- @abstractmethod
- def get_document_embedder(self, *args, **kwargs):
- ...
-
- def get_model(self):
- return self._embedding_model
-
-
-class DocumentStoreProvider(metaclass=ABCMeta):
- @abstractmethod
- def get_store(self, *args, **kwargs) -> DocumentStore:
- ...
-
- @abstractmethod
- def get_retriever(self, *args, **kwargs):
- ...
diff --git a/wren-ai-service/src/force_deploy.py b/wren-ai-service/src/force_deploy.py
deleted file mode 100644
index 281597d83..000000000
--- a/wren-ai-service/src/force_deploy.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# This file is only used for OSS, it will force deploy the mdl for the OSS users
-# Since we allow users to customize llm and embedding models, which means qdrant collections may need to be recreated
-# So, this file automates the process of force deploying the mdl
-
-import asyncio
-import os
-from pathlib import Path
-
-import aiohttp
-import backoff
-from dotenv import load_dotenv
-
-if Path(".env.dev").exists():
- load_dotenv(".env.dev", override=True)
-
-
-@backoff.on_exception(backoff.expo, aiohttp.ClientError, max_time=60, max_tries=3)
-async def force_deploy():
- async with aiohttp.ClientSession() as session:
- async with session.post(
- f"{os.getenv("WREN_UI_ENDPOINT", "http://wren-ui:3000")}/api/graphql",
- json={
- "query": "mutation Deploy($force: Boolean) { deploy(force: $force) }",
- "variables": {"force": True},
- },
- timeout=aiohttp.ClientTimeout(total=60), # 60 seconds
- ) as response:
- res = await response.json()
- print(f"Forcing deployment: {res}")
-
-
-if os.getenv("ENGINE", "wren_ui") == "wren_ui":
- asyncio.run(force_deploy())
diff --git a/wren-ai-service/src/force_update_config.py b/wren-ai-service/src/force_update_config.py
deleted file mode 100644
index 21c345633..000000000
--- a/wren-ai-service/src/force_update_config.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# This file is only used for local development
-# It will update the config.yaml file to use correct engine name for all pipelines
-# Since the demo app uses the same config.yaml and the app will update the engine names while deploying mdl,
-# so we need to force update the engine names to the correct ones when we would like to use Wren UI
-
-import yaml
-
-
-def update_config():
- # Read the config file
- with open("config.yaml", "r") as file:
- # Load all documents from YAML file (since it has multiple documents separated by ---)
- documents = list(yaml.safe_load_all(file))
-
- # Find the pipeline configuration document
- for doc in documents:
- if doc.get("type") == "pipeline":
- # Update engine name in all pipelines
- for pipe in doc.get("pipes", []):
- if "engine" in pipe:
- if pipe["name"] in [
- "sql_functions_retrieval",
- "sql_knowledge_retrieval",
- ]:
- pipe["engine"] = "wren_ibis"
- else:
- pipe["engine"] = "wren_ui"
-
- # Write back to the file
- with open("config.yaml", "w") as file:
- yaml.safe_dump_all(documents, file, default_flow_style=False)
-
- print("Successfully updated engine names to 'wren_ui' in all pipelines")
-
-
-if __name__ == "__main__":
- update_config()
diff --git a/wren-ai-service/src/globals.py b/wren-ai-service/src/globals.py
deleted file mode 100644
index 934334461..000000000
--- a/wren-ai-service/src/globals.py
+++ /dev/null
@@ -1,340 +0,0 @@
-import logging
-from dataclasses import dataclass
-
-import toml
-
-from src.config import Settings
-from src.core.pipeline import PipelineComponent
-from src.core.provider import EmbedderProvider, LLMProvider
-from src.pipelines import generation, indexing, retrieval
-from src.utils import fetch_wren_ai_docs
-from src.web.v1 import services
-
-logger = logging.getLogger("wren-ai-service")
-
-
-@dataclass
-class ServiceContainer:
- ask_service: services.AskService
- ask_feedback_service: services.AskFeedbackService
- question_recommendation: services.QuestionRecommendation
- relationship_recommendation: services.RelationshipRecommendation
- semantics_description: services.SemanticsDescription
- semantics_preparation_service: services.SemanticsPreparationService
- chart_service: services.ChartService
- chart_adjustment_service: services.ChartAdjustmentService
- sql_answer_service: services.SqlAnswerService
- sql_pairs_service: services.SqlPairsService
- sql_question_service: services.SqlQuestionService
- instructions_service: services.InstructionsService
- sql_correction_service: services.SqlCorrectionService
-
-
-@dataclass
-class ServiceMetadata:
- pipes_metadata: dict
- service_version: str
-
-
-def create_service_container(
- pipe_components: dict[str, PipelineComponent],
- settings: Settings,
-) -> ServiceContainer:
- query_cache = {
- "maxsize": settings.query_cache_maxsize,
- "ttl": settings.query_cache_ttl,
- }
- wren_ai_docs = fetch_wren_ai_docs(settings.doc_endpoint, settings.is_oss)
- if not wren_ai_docs:
- logger.warning("Failed to fetch Wren AI docs or response was empty.")
-
- _db_schema_retrieval_pipeline = retrieval.DbSchemaRetrieval(
- **pipe_components["db_schema_retrieval"],
- table_retrieval_size=settings.table_retrieval_size,
- table_column_retrieval_size=settings.table_column_retrieval_size,
- )
- _sql_pair_indexing_pipeline = indexing.SqlPairs(
- **pipe_components["sql_pairs_indexing"],
- sql_pairs_path=settings.sql_pairs_path,
- )
- _instructions_indexing_pipeline = indexing.Instructions(
- **pipe_components["instructions_indexing"],
- )
- _sql_pair_retrieval_pipeline = retrieval.SqlPairsRetrieval(
- **pipe_components["sql_pairs_retrieval"],
- sql_pairs_similarity_threshold=settings.sql_pairs_similarity_threshold,
- sql_pairs_retrieval_max_size=settings.sql_pairs_retrieval_max_size,
- )
- _instructions_retrieval_pipeline = retrieval.Instructions(
- **pipe_components["instructions_retrieval"],
- similarity_threshold=settings.instructions_similarity_threshold,
- top_k=settings.instructions_top_k,
- )
- _sql_correction_pipeline = generation.SQLCorrection(
- **pipe_components["sql_correction"],
- )
- _sql_functions_retrieval_pipeline = retrieval.SqlFunctions(
- **pipe_components["sql_functions_retrieval"],
- )
- _sql_executor_pipeline = retrieval.SQLExecutor(
- **pipe_components["sql_executor"],
- )
- _sql_diagnosis_pipeline = generation.SQLDiagnosis(
- **pipe_components["sql_diagnosis"],
- )
-
- return ServiceContainer(
- semantics_description=services.SemanticsDescription(
- pipelines={
- "semantics_description": generation.SemanticsDescription(
- **pipe_components["semantics_description"],
- )
- },
- **query_cache,
- ),
- semantics_preparation_service=services.SemanticsPreparationService(
- pipelines={
- "db_schema": indexing.DBSchema(
- **pipe_components["db_schema_indexing"],
- column_batch_size=settings.column_indexing_batch_size,
- ),
- "historical_question": indexing.HistoricalQuestion(
- **pipe_components["historical_question_indexing"],
- ),
- "table_description": indexing.TableDescription(
- **pipe_components["table_description_indexing"],
- ),
- "sql_pairs": _sql_pair_indexing_pipeline,
- "instructions": _instructions_indexing_pipeline,
- "project_meta": indexing.ProjectMeta(
- **pipe_components["project_meta_indexing"],
- ),
- },
- **query_cache,
- ),
- ask_service=services.AskService(
- pipelines={
- "intent_classification": generation.IntentClassification(
- **pipe_components["intent_classification"],
- wren_ai_docs=wren_ai_docs,
- ),
- "misleading_assistance": generation.MisleadingAssistance(
- **pipe_components["misleading_assistance"],
- ),
- "data_assistance": generation.DataAssistance(
- **pipe_components["data_assistance"]
- ),
- "user_guide_assistance": generation.UserGuideAssistance(
- **pipe_components["user_guide_assistance"],
- wren_ai_docs=wren_ai_docs,
- ),
- "db_schema_retrieval": _db_schema_retrieval_pipeline,
- "historical_question": retrieval.HistoricalQuestionRetrieval(
- **pipe_components["historical_question_retrieval"],
- historical_question_retrieval_similarity_threshold=settings.historical_question_retrieval_similarity_threshold,
- ),
- "sql_pairs_retrieval": _sql_pair_retrieval_pipeline,
- "instructions_retrieval": _instructions_retrieval_pipeline,
- "sql_generation": generation.SQLGeneration(
- **pipe_components["sql_generation"],
- ),
- "sql_generation_reasoning": generation.SQLGenerationReasoning(
- **pipe_components["sql_generation_reasoning"],
- ),
- "followup_sql_generation_reasoning": generation.FollowUpSQLGenerationReasoning(
- **pipe_components["followup_sql_generation_reasoning"],
- ),
- "sql_correction": _sql_correction_pipeline,
- "followup_sql_generation": generation.FollowUpSQLGeneration(
- **pipe_components["followup_sql_generation"],
- ),
- "sql_functions_retrieval": _sql_functions_retrieval_pipeline,
- "sql_diagnosis": _sql_diagnosis_pipeline,
- "sql_knowledge_retrieval": retrieval.SqlKnowledges(
- **pipe_components["sql_knowledge_retrieval"],
- ),
- },
- allow_intent_classification=settings.allow_intent_classification,
- allow_sql_generation_reasoning=settings.allow_sql_generation_reasoning,
- allow_sql_functions_retrieval=settings.allow_sql_functions_retrieval,
- allow_sql_diagnosis=settings.allow_sql_diagnosis,
- allow_sql_knowledge_retrieval=settings.allow_sql_knowledge_retrieval,
- max_histories=settings.max_histories,
- enable_column_pruning=settings.enable_column_pruning,
- max_sql_correction_retries=settings.max_sql_correction_retries,
- **query_cache,
- ),
- ask_feedback_service=services.AskFeedbackService(
- pipelines={
- "db_schema_retrieval": _db_schema_retrieval_pipeline,
- "sql_pairs_retrieval": _sql_pair_retrieval_pipeline,
- "instructions_retrieval": _instructions_retrieval_pipeline,
- "sql_functions_retrieval": _sql_functions_retrieval_pipeline,
- "sql_regeneration": generation.SQLRegeneration(
- **pipe_components["sql_regeneration"],
- ),
- "sql_correction": _sql_correction_pipeline,
- "sql_diagnosis": _sql_diagnosis_pipeline,
- "sql_knowledge_retrieval": retrieval.SqlKnowledges(
- **pipe_components["sql_knowledge_retrieval"],
- ),
- },
- allow_sql_functions_retrieval=settings.allow_sql_functions_retrieval,
- allow_sql_diagnosis=settings.allow_sql_diagnosis,
- allow_sql_knowledge_retrieval=settings.allow_sql_knowledge_retrieval,
- **query_cache,
- ),
- chart_service=services.ChartService(
- pipelines={
- "sql_executor": _sql_executor_pipeline,
- "chart_generation": generation.ChartGeneration(
- **pipe_components["chart_generation"],
- ),
- },
- **query_cache,
- ),
- chart_adjustment_service=services.ChartAdjustmentService(
- pipelines={
- "sql_executor": _sql_executor_pipeline,
- "chart_adjustment": generation.ChartAdjustment(
- **pipe_components["chart_adjustment"],
- ),
- },
- **query_cache,
- ),
- sql_answer_service=services.SqlAnswerService(
- pipelines={
- "preprocess_sql_data": retrieval.PreprocessSqlData(
- **pipe_components["preprocess_sql_data"],
- ),
- "sql_answer": generation.SQLAnswer(
- **pipe_components["sql_answer"],
- ),
- },
- **query_cache,
- ),
- relationship_recommendation=services.RelationshipRecommendation(
- pipelines={
- "relationship_recommendation": generation.RelationshipRecommendation(
- **pipe_components["relationship_recommendation"],
- )
- },
- **query_cache,
- ),
- question_recommendation=services.QuestionRecommendation(
- pipelines={
- "question_recommendation": generation.QuestionRecommendation(
- **pipe_components["question_recommendation"],
- ),
- "db_schema_retrieval": _db_schema_retrieval_pipeline,
- "sql_generation": generation.SQLGeneration(
- **pipe_components["question_recommendation_sql_generation"],
- ),
- "sql_pairs_retrieval": _sql_pair_retrieval_pipeline,
- "instructions_retrieval": _instructions_retrieval_pipeline,
- "sql_functions_retrieval": _sql_functions_retrieval_pipeline,
- "sql_knowledge_retrieval": retrieval.SqlKnowledges(
- **pipe_components["sql_knowledge_retrieval"],
- ),
- },
- allow_sql_functions_retrieval=settings.allow_sql_functions_retrieval,
- allow_sql_knowledge_retrieval=settings.allow_sql_knowledge_retrieval,
- **query_cache,
- ),
- sql_pairs_service=services.SqlPairsService(
- pipelines={
- "sql_pairs": _sql_pair_indexing_pipeline,
- },
- **query_cache,
- ),
- sql_question_service=services.SqlQuestionService(
- pipelines={
- "sql_question_generation": generation.SQLQuestion(
- **pipe_components["sql_question_generation"],
- )
- },
- **query_cache,
- ),
- instructions_service=services.InstructionsService(
- pipelines={
- "instructions_indexing": _instructions_indexing_pipeline,
- },
- **query_cache,
- ),
- sql_correction_service=services.SqlCorrectionService(
- pipelines={
- "sql_tables_extraction": generation.SQLTablesExtraction(
- **pipe_components["sql_tables_extraction"],
- ),
- "db_schema_retrieval": _db_schema_retrieval_pipeline,
- "sql_correction": _sql_correction_pipeline,
- "sql_knowledge_retrieval": retrieval.SqlKnowledges(
- **pipe_components["sql_knowledge_retrieval"],
- ),
- },
- allow_sql_knowledge_retrieval=settings.allow_sql_knowledge_retrieval,
- **query_cache,
- ),
- )
-
-
-# Create a dependency that will be used to access the ServiceContainer
-def get_service_container():
- from src.__main__ import app
-
- return app.state.service_container
-
-
-def create_service_metadata(
- pipe_components: dict[str, PipelineComponent],
- pyproject_path: str = "pyproject.toml",
-) -> ServiceMetadata:
- """
- This service metadata is used for logging purposes and will be sent to Langfuse.
- """
-
- def _get_version_from_pyproject() -> str:
- with open(pyproject_path, "r") as f:
- pyproject = toml.load(f)
- return pyproject["tool"]["poetry"]["version"]
-
- def _convert_pipe_metadata(
- llm_provider: LLMProvider,
- embedder_provider: EmbedderProvider,
- **_,
- ) -> dict:
- llm_metadata = (
- {
- "llm_model": llm_provider.get_model(),
- "llm_model_kwargs": llm_provider.get_model_kwargs(),
- }
- if llm_provider
- else {}
- )
-
- embedding_metadata = (
- {
- "embedding_model": embedder_provider.get_model(),
- }
- if embedder_provider
- else {}
- )
- return {**llm_metadata, **embedding_metadata}
-
- pipes_metadata = {
- pipe_name: _convert_pipe_metadata(**dict(component))
- for pipe_name, component in pipe_components.items()
- }
-
- service_version = _get_version_from_pyproject()
-
- logger.info(f"Service version: {service_version}")
-
- return ServiceMetadata(pipes_metadata, service_version)
-
-
-# Create a dependency that will be used to access the ServiceMetadata
-def get_service_metadata():
- from src.__main__ import app
-
- return app.state.service_metadata
diff --git a/wren-ai-service/src/pipelines/__init__.py b/wren-ai-service/src/pipelines/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/wren-ai-service/src/pipelines/common.py b/wren-ai-service/src/pipelines/common.py
deleted file mode 100644
index f6114d63b..000000000
--- a/wren-ai-service/src/pipelines/common.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import re
-from typing import Any, List, Optional, Tuple
-
-from haystack import Document, component
-
-
-def get_engine_supported_data_type(data_type: str) -> str:
- """
- This function makes sure downstream ai pipeline get column data types in a format that is supported by the data engine.
- """
- match data_type.upper():
- case "BPCHAR" | "NAME" | "UUID" | "INET":
- return "VARCHAR"
- case "OID":
- return "INT"
- case "BIGNUMERIC":
- return "NUMERIC"
- case "BYTES":
- return "BYTEA"
- case "DATETIME":
- return "TIMESTAMP"
- case "FLOAT64":
- return "DOUBLE"
- case "INT64":
- return "BIGINT"
- case _:
- return data_type.upper()
-
-
-def build_table_ddl(
- content: dict, columns: Optional[set[str]] = None, tables: Optional[set[str]] = None
-) -> Tuple[str, bool, bool]:
- columns_ddl = []
- has_calculated_field = False
- has_json_field = False
-
- for column in content["columns"]:
- if column["type"] == "COLUMN":
- if (
- (not columns or (columns and column["name"] in columns))
- and column["data_type"].lower()
- != "unknown" # quick fix: filtering out UNKNOWN column type
- ):
- if "This column is a Calculated Field" in column["comment"]:
- has_calculated_field = True
- if column["data_type"].lower() == "json":
- has_json_field = True
- column_ddl = f"{column['comment']}{column['name']} {get_engine_supported_data_type(column['data_type'])}"
- if column["is_primary_key"]:
- column_ddl += " PRIMARY KEY"
- columns_ddl.append(column_ddl)
- elif column["type"] == "FOREIGN_KEY":
- if not tables or (tables and set(column["tables"]).issubset(tables)):
- columns_ddl.append(f"{column['comment']}{column['constraint']}")
-
- return (
- (
- f"{content['comment']}CREATE TABLE {content['name']} (\n "
- + ",\n ".join(columns_ddl)
- + "\n);"
- ),
- has_calculated_field,
- has_json_field,
- )
-
-
-async def retrieve_metadata(project_id: str, retriever) -> dict[str, Any]:
- filters = None
- if project_id:
- filters = {
- "operator": "AND",
- "conditions": [
- {"field": "project_id", "operator": "==", "value": project_id},
- ],
- }
-
- result = await retriever.run(query_embedding=[], filters=filters)
- documents = result["documents"]
-
- # only one document for a project, thus we can return the first one
- if documents:
- doc = documents[0]
- return doc.meta
- else:
- return {}
-
-
-@component
-class ScoreFilter:
- @component.output_types(
- documents=List[Document],
- )
- def run(
- self,
- documents: List[Document],
- score: float = 0.9,
- max_size: int = 10,
- ):
- return {
- "documents": sorted(
- filter(lambda document: document.score >= score, documents),
- key=lambda document: document.score,
- reverse=True,
- )[:max_size]
- }
-
-
-MULTIPLE_NEW_LINE_REGEX = re.compile(r"\n{3,}")
-
-
-def clean_up_new_lines(text: str) -> str:
- return MULTIPLE_NEW_LINE_REGEX.sub("\n\n\n", text)
diff --git a/wren-ai-service/src/pipelines/generation/__init__.py b/wren-ai-service/src/pipelines/generation/__init__.py
deleted file mode 100644
index 891077a28..000000000
--- a/wren-ai-service/src/pipelines/generation/__init__.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from .chart_adjustment import ChartAdjustment
-from .chart_generation import ChartGeneration
-from .data_assistance import DataAssistance
-from .followup_sql_generation import FollowUpSQLGeneration
-from .followup_sql_generation_reasoning import FollowUpSQLGenerationReasoning
-from .intent_classification import IntentClassification
-from .misleading_assistance import MisleadingAssistance
-from .question_recommendation import QuestionRecommendation
-from .relationship_recommendation import RelationshipRecommendation
-from .semantics_description import SemanticsDescription
-from .sql_answer import SQLAnswer
-from .sql_correction import SQLCorrection
-from .sql_diagnosis import SQLDiagnosis
-from .sql_generation import SQLGeneration
-from .sql_generation_reasoning import SQLGenerationReasoning
-from .sql_question import SQLQuestion
-from .sql_regeneration import SQLRegeneration
-from .sql_tables_extraction import SQLTablesExtraction
-from .user_guide_assistance import UserGuideAssistance
-
-__all__ = [
- "ChartGeneration",
- "ChartAdjustment",
- "DataAssistance",
- "FollowUpSQLGeneration",
- "IntentClassification",
- "QuestionRecommendation",
- "RelationshipRecommendation",
- "SemanticsDescription",
- "SQLAnswer",
- "SQLCorrection",
- "SQLDiagnosis",
- "SQLGeneration",
- "SQLGenerationReasoning",
- "UserGuideAssistance",
- "SQLQuestion",
- "SQLRegeneration",
- "FollowUpSQLGenerationReasoning",
- "MisleadingAssistance",
- "SQLTablesExtraction",
-]
diff --git a/wren-ai-service/src/pipelines/generation/chart_adjustment.py b/wren-ai-service/src/pipelines/generation/chart_adjustment.py
deleted file mode 100644
index 2e4e7ba8a..000000000
--- a/wren-ai-service/src/pipelines/generation/chart_adjustment.py
+++ /dev/null
@@ -1,202 +0,0 @@
-import logging
-import sys
-from typing import Any, Dict
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.generation.utils.chart import (
- ChartDataPreprocessor,
- ChartGenerationPostProcessor,
- ChartGenerationResults,
- chart_generation_instructions,
-)
-from src.utils import trace_cost
-from src.web.v1.services.chart_adjustment import ChartAdjustmentOption
-
-logger = logging.getLogger("wren-ai-service")
-
-
-chart_adjustment_system_prompt = f"""
-### TASK ###
-
-You are a data analyst great at visualizing data using vega-lite! Given the user's question, SQL, sample data, sample column values, original vega-lite schema and adjustment options,
-you need to re-generate vega-lite schema in JSON and provide suitable chart type.
-Besides, you need to give a concise and easy-to-understand reasoning to describe why you provide such vega-lite schema based on the question, SQL, sample data, sample column values, original vega-lite schema and adjustment options.
-
-{chart_generation_instructions}
-- If you think the adjustment options are not suitable for the data, you can return an empty string for the schema and chart type and give reasoning to explain why.
-
-### OUTPUT FORMAT ###
-
-Please provide your chain of thought reasoning, chart type and the vega-lite schema in JSON format.
-
-{{
- "reasoning": ,
- "chart_type": "line" | "multi_line" | "bar" | "pie" | "grouped_bar" | "stacked_bar" | "area" | "",
- "chart_schema":
-}}
-"""
-
-chart_adjustment_user_prompt_template = """
-### INPUT ###
-Original Question: {{ query }}
-Original SQL: {{ sql }}
-Original Vega-Lite Schema: {{ chart_schema }}
-Sample Data: {{ sample_data }}
-Sample Column Values: {{ sample_column_values }}
-Language: {{ language }}
-
-Adjustment Options:
-- Chart Type: {{ adjustment_option.chart_type }}
-{% if adjustment_option.chart_type != "pie" %}
-{% if adjustment_option.x_axis %}
-- X Axis: {{ adjustment_option.x_axis }}
-{% endif %}
-{% if adjustment_option.y_axis %}
-- Y Axis: {{ adjustment_option.y_axis }}
-{% endif %}
-{% endif %}
-{% if adjustment_option.x_offset and adjustment_option.chart_type == "grouped_bar" %}
-- X Offset: {{ adjustment_option.x_offset }}
-{% endif %}
-{% if adjustment_option.color and adjustment_option.chart_type != "area" %}
-- Color: {{ adjustment_option.color }}
-{% endif %}
-{% if adjustment_option.theta and adjustment_option.chart_type == "pie" %}
-- Theta: {{ adjustment_option.theta }}
-{% endif %}
-
-Please think step by step
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def preprocess_data(
- data: Dict[str, Any], chart_data_preprocessor: ChartDataPreprocessor
-) -> dict:
- return chart_data_preprocessor.run(data)
-
-
-@observe(capture_input=False)
-def prompt(
- query: str,
- sql: str,
- adjustment_option: ChartAdjustmentOption,
- chart_schema: dict,
- preprocess_data: dict,
- language: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- sample_data = preprocess_data.get("sample_data")
- sample_column_values = preprocess_data.get("sample_column_values")
-
- _prompt = prompt_builder.run(
- query=query,
- sql=sql,
- adjustment_option=adjustment_option,
- chart_schema=chart_schema,
- sample_data=sample_data,
- sample_column_values=sample_column_values,
- language=language,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_chart_adjustment(
- prompt: dict,
- generator: Any,
- generator_name: str,
-) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def post_process(
- generate_chart_adjustment: dict,
- vega_schema: Dict[str, Any],
- preprocess_data: dict,
- post_processor: ChartGenerationPostProcessor,
-) -> dict:
- return post_processor.run(
- generate_chart_adjustment.get("replies"),
- vega_schema,
- preprocess_data["sample_data"],
- )
-
-
-## End of Pipeline
-CHART_ADJUSTMENT_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "chart_adjustment_results",
- "schema": ChartGenerationResults.model_json_schema(),
- },
- }
-}
-
-
-class ChartAdjustment(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._components = {
- "prompt_builder": PromptBuilder(
- template=chart_adjustment_user_prompt_template
- ),
- "generator": llm_provider.get_generator(
- system_prompt=chart_adjustment_system_prompt,
- generation_kwargs=CHART_ADJUSTMENT_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "chart_data_preprocessor": ChartDataPreprocessor(),
- "post_processor": ChartGenerationPostProcessor(),
- }
-
- with open("src/pipelines/generation/utils/vega-lite-schema-v5.json", "r") as f:
- _vega_schema = orjson.loads(f.read())
-
- self._configs = {
- "vega_schema": _vega_schema,
- }
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Chart Adjustment")
- async def run(
- self,
- query: str,
- sql: str,
- adjustment_option: ChartAdjustmentOption,
- chart_schema: dict,
- data: dict,
- language: str,
- ) -> dict:
- logger.info("Chart Adjustment pipeline is running...")
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "sql": sql,
- "adjustment_option": adjustment_option,
- "chart_schema": chart_schema,
- "data": data,
- "language": language,
- **self._components,
- **self._configs,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/chart_generation.py b/wren-ai-service/src/pipelines/generation/chart_generation.py
deleted file mode 100644
index 6daca5ec1..000000000
--- a/wren-ai-service/src/pipelines/generation/chart_generation.py
+++ /dev/null
@@ -1,175 +0,0 @@
-import logging
-import sys
-from typing import Any, Dict, Optional
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.generation.utils.chart import (
- ChartDataPreprocessor,
- ChartGenerationPostProcessor,
- ChartGenerationResults,
- chart_generation_instructions,
-)
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-chart_generation_system_prompt = f"""
-### TASK ###
-
-You are a data analyst great at visualizing data using vega-lite! Given the user's question, SQL, sample data and sample column values, you need to generate vega-lite schema in JSON and provide suitable chart type.
-Besides, you need to give a concise and easy-to-understand reasoning to describe why you provide such vega-lite schema based on the question, SQL, sample data and sample column values.
-
-{chart_generation_instructions}
-- If the user provides a custom instruction, it should be followed strictly and you should use it to change the style of response for reasoning.
-
-### OUTPUT FORMAT ###
-
-Please provide your chain of thought reasoning, chart type and the vega-lite schema in JSON format.
-
-{{
- "reasoning": ,
- "chart_type": "line" | "multi_line" | "bar" | "pie" | "grouped_bar" | "stacked_bar" | "area" | "",
- "chart_schema":
-}}
-"""
-
-chart_generation_user_prompt_template = """
-### INPUT ###
-Question: {{ query }}
-SQL: {{ sql }}
-Sample Data: {{ sample_data }}
-Sample Column Values: {{ sample_column_values }}
-Language: {{ language }}
-Custom Instruction: {{ custom_instruction }}
-
-Please think step by step
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def preprocess_data(
- data: Dict[str, Any], chart_data_preprocessor: ChartDataPreprocessor
-) -> dict:
- return chart_data_preprocessor.run(data)
-
-
-@observe(capture_input=False)
-def prompt(
- query: str,
- sql: str,
- preprocess_data: dict,
- language: str,
- custom_instruction: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- sample_data = preprocess_data.get("sample_data")
- sample_column_values = preprocess_data.get("sample_column_values")
-
- _prompt = prompt_builder.run(
- query=query,
- sql=sql,
- sample_data=sample_data,
- sample_column_values=sample_column_values,
- language=language,
- custom_instruction=custom_instruction,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_chart(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def post_process(
- generate_chart: dict,
- vega_schema: Dict[str, Any],
- remove_data_from_chart_schema: bool,
- preprocess_data: dict,
- post_processor: ChartGenerationPostProcessor,
-) -> dict:
- return post_processor.run(
- generate_chart.get("replies"),
- vega_schema,
- preprocess_data["sample_data"],
- remove_data_from_chart_schema,
- )
-
-
-## End of Pipeline
-CHART_GENERATION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "chart_generation_schema",
- "schema": ChartGenerationResults.model_json_schema(),
- },
- }
-}
-
-
-class ChartGeneration(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._components = {
- "prompt_builder": PromptBuilder(
- template=chart_generation_user_prompt_template
- ),
- "generator": llm_provider.get_generator(
- system_prompt=chart_generation_system_prompt,
- generation_kwargs=CHART_GENERATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "chart_data_preprocessor": ChartDataPreprocessor(),
- "post_processor": ChartGenerationPostProcessor(),
- }
-
- with open("src/pipelines/generation/utils/vega-lite-schema-v5.json", "r") as f:
- _vega_schema = orjson.loads(f.read())
-
- self._configs = {
- "vega_schema": _vega_schema,
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Chart Generation")
- async def run(
- self,
- query: str,
- sql: str,
- data: dict,
- language: str,
- remove_data_from_chart_schema: bool = True,
- custom_instruction: Optional[str] = None,
- ) -> dict:
- logger.info("Chart Generation pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "sql": sql,
- "data": data,
- "language": language,
- "remove_data_from_chart_schema": remove_data_from_chart_schema,
- "custom_instruction": custom_instruction or "",
- **self._components,
- **self._configs,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/data_assistance.py b/wren-ai-service/src/pipelines/generation/data_assistance.py
deleted file mode 100644
index 51b91197f..000000000
--- a/wren-ai-service/src/pipelines/generation/data_assistance.py
+++ /dev/null
@@ -1,171 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-data_assistance_system_prompt = """
-### TASK ###
-You are a data analyst great at answering user's questions about given database schema.
-Please carefully read user's question and database schema to answer it in easy to understand manner
-using the Markdown format. Your goal is to help guide user understand its database!
-
-### INSTRUCTIONS ###
-
-- Answer must be in the same language user specified.
-- There should be proper line breaks, whitespace, and Markdown formatting(headers, lists, tables, etc.) in your response.
-- If the language is Traditional/Simplified Chinese, Korean, or Japanese, the maximum response length is 150 words; otherwise, the maximum response length is 110 words.
-- MUST NOT add SQL code in your response.
-- If the user provides a custom instruction, it should be followed strictly and you should use it to change the style of response.
-
-### OUTPUT FORMAT ###
-Please provide your response in proper Markdown format without ```markdown``` tags.
-"""
-
-data_assistance_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for db_schema in db_schemas %}
- {{ db_schema }}
-{% endfor %}
-
-### INPUT ###
-User's question: {{query}}
-Language: {{language}}
-
-Custom Instruction: {{ custom_instruction }}
-
-Please think step by step
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- db_schemas: list[str],
- language: str,
- histories: list[AskHistory],
- prompt_builder: PromptBuilder,
- custom_instruction: str,
-) -> dict:
- previous_query_summaries = (
- [history.question for history in histories] if histories else []
- )
- query = "\n".join(previous_query_summaries) + "\n" + query
-
- _prompt = prompt_builder.run(
- query=query,
- db_schemas=db_schemas,
- language=language,
- custom_instruction=custom_instruction,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def data_assistance(
- prompt: dict, generator: Any, query_id: str, generator_name: str
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"),
- query_id=query_id,
- ), generator_name
-
-
-## End of Pipeline
-
-
-class DataAssistance(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=data_assistance_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=data_assistance_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Create a new queue for the user if it doesn't exist
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Ensure the user's queue exists
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="Data Assistance")
- async def run(
- self,
- query: str,
- db_schemas: list[str],
- language: str,
- query_id: Optional[str] = None,
- histories: Optional[list[AskHistory]] = None,
- custom_instruction: Optional[str] = None,
- ):
- logger.info("Data Assistance pipeline is running...")
- return await self._pipe.execute(
- ["data_assistance"],
- inputs={
- "query": query,
- "db_schemas": db_schemas,
- "language": language,
- "query_id": query_id or "",
- "histories": histories or [],
- "custom_instruction": custom_instruction or "",
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/followup_sql_generation.py b/wren-ai-service/src/pipelines/generation/followup_sql_generation.py
deleted file mode 100644
index 35cfb8fcc..000000000
--- a/wren-ai-service/src/pipelines/generation/followup_sql_generation.py
+++ /dev/null
@@ -1,239 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.engine import Engine
-from src.core.pipeline import BasicPipeline
-from src.core.provider import DocumentStoreProvider, LLMProvider
-from src.pipelines.common import clean_up_new_lines, retrieve_metadata
-from src.pipelines.generation.utils.sql import (
- SQL_GENERATION_MODEL_KWARGS,
- SQLGenPostProcessor,
- construct_ask_history_messages,
- construct_instructions,
- get_calculated_field_instructions,
- get_json_field_instructions,
- get_metric_instructions,
- get_sql_generation_system_prompt,
-)
-from src.pipelines.retrieval.sql_functions import SqlFunction
-from src.pipelines.retrieval.sql_knowledge import SqlKnowledge
-from src.utils import trace_cost
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-text_to_sql_with_followup_user_prompt_template = """
-### TASK ###
-Given the following user's follow-up question and previous SQL query and summary,
-generate one SQL query to best answer user's question.
-
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-{% if calculated_field_instructions %}
-{{ calculated_field_instructions }}
-{% endif %}
-
-{% if metric_instructions %}
-{{ metric_instructions }}
-{% endif %}
-
-{% if json_field_instructions %}
-{{ json_field_instructions }}
-{% endif %}
-
-{% if sql_functions %}
-### SQL FUNCTIONS ###
-{% for function in sql_functions %}
-{{ function }}
-{% endfor %}
-{% endif %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sample in sql_samples %}
-Summary:
-{{sample.summary}}
-SQL:
-{{sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### QUESTION ###
-User's Follow-up Question: {{ query }}
-
-### REASONING PLAN ###
-{{ sql_generation_reasoning }}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- documents: list[str],
- sql_generation_reasoning: str,
- prompt_builder: PromptBuilder,
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- documents=documents,
- sql_generation_reasoning=sql_generation_reasoning,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- calculated_field_instructions=(
- get_calculated_field_instructions(sql_knowledge)
- if has_calculated_field
- else ""
- ),
- metric_instructions=(
- get_metric_instructions(sql_knowledge) if has_metric else ""
- ),
- json_field_instructions=(
- get_json_field_instructions(sql_knowledge) if has_json_field else ""
- ),
- sql_samples=sql_samples,
- sql_functions=sql_functions,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_in_followup(
- prompt: dict,
- generator: Any,
- histories: list[AskHistory],
- generator_name: str,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- history_messages = construct_ask_history_messages(histories)
- current_system_prompt = get_sql_generation_system_prompt(sql_knowledge)
- return await generator(
- prompt=prompt.get("prompt"),
- history_messages=history_messages,
- current_system_prompt=current_system_prompt,
- ), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- generate_sql_in_followup: dict,
- post_processor: SQLGenPostProcessor,
- data_source: str,
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
-) -> dict:
- return await post_processor.run(
- generate_sql_in_followup.get("replies"),
- project_id=project_id,
- use_dry_plan=use_dry_plan,
- data_source=data_source,
- allow_dry_plan_fallback=allow_dry_plan_fallback,
- )
-
-
-## End of Pipeline
-
-
-class FollowUpSQLGeneration(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- document_store_provider: DocumentStoreProvider,
- engine: Engine,
- **kwargs,
- ):
- self._retriever = document_store_provider.get_retriever(
- document_store_provider.get_store("project_meta")
- )
-
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=get_sql_generation_system_prompt(None),
- generation_kwargs=SQL_GENERATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=text_to_sql_with_followup_user_prompt_template
- ),
- "post_processor": SQLGenPostProcessor(engine=engine),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Follow-Up SQL Generation")
- async def run(
- self,
- query: str,
- contexts: list[str],
- sql_generation_reasoning: str,
- histories: list[AskHistory],
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- project_id: str | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- sql_knowledge: SqlKnowledge | None = None,
- ):
- logger.info("Follow-Up SQL Generation pipeline is running...")
-
- if use_dry_plan:
- metadata = await retrieve_metadata(project_id or "", self._retriever)
- else:
- metadata = {}
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "documents": contexts,
- "sql_generation_reasoning": sql_generation_reasoning,
- "histories": histories,
- "project_id": project_id,
- "sql_samples": sql_samples,
- "instructions": instructions,
- "has_calculated_field": has_calculated_field,
- "has_metric": has_metric,
- "has_json_field": has_json_field,
- "sql_functions": sql_functions,
- "use_dry_plan": use_dry_plan,
- "allow_dry_plan_fallback": allow_dry_plan_fallback,
- "data_source": metadata.get("data_source", "local_file"),
- "sql_knowledge": sql_knowledge,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/followup_sql_generation_reasoning.py b/wren-ai-service/src/pipelines/generation/followup_sql_generation_reasoning.py
deleted file mode 100644
index 42b28c5b8..000000000
--- a/wren-ai-service/src/pipelines/generation/followup_sql_generation_reasoning.py
+++ /dev/null
@@ -1,193 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.generation.utils.sql import (
- construct_instructions,
- sql_generation_reasoning_system_prompt,
-)
-from src.utils import trace_cost
-from src.web.v1.services import Configuration
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_generation_reasoning_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sql_sample in sql_samples %}
-Question:
-{{sql_sample.question}}
-SQL:
-{{sql_sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### User's QUERY HISTORY ###
-{% for history in histories %}
-Question:
-{{ history.question }}
-SQL:
-{{ history.sql }}
-{% endfor %}
-
-### QUESTION ###
-User's Question: {{ query }}
-Language: {{ language }}
-Current Time: {{ current_time }}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- documents: list[str],
- histories: list[AskHistory],
- sql_samples: list[dict],
- instructions: list[dict],
- prompt_builder: PromptBuilder,
- configuration: Configuration | None = Configuration(),
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- documents=documents,
- histories=histories,
- sql_samples=sql_samples,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- language=configuration.language,
- current_time=configuration.show_current_time(),
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_reasoning(
- prompt: dict,
- generator: Any,
- query_id: str,
- generator_name: str,
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"),
- query_id=query_id,
- ), generator_name
-
-
-@observe()
-def post_process(
- generate_sql_reasoning: dict,
-) -> dict:
- return generate_sql_reasoning.get("replies")[0]
-
-
-## End of Pipeline
-
-
-class FollowUpSQLGenerationReasoning(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=sql_generation_reasoning_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_generation_reasoning_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[query_id] = asyncio.Queue()
-
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[query_id] = asyncio.Queue()
-
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="FollowupSQL Generation Reasoning")
- async def run(
- self,
- query: str,
- contexts: list[str],
- histories: list[AskHistory],
- sql_samples: Optional[list[dict]] = None,
- instructions: Optional[list[dict]] = None,
- configuration: Configuration = Configuration(),
- query_id: Optional[str] = None,
- ):
- logger.info("Followup SQL Generation Reasoning pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "documents": contexts,
- "histories": histories,
- "sql_samples": sql_samples or [],
- "instructions": instructions or [],
- "configuration": configuration,
- "query_id": query_id,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/intent_classification.py b/wren-ai-service/src/pipelines/generation/intent_classification.py
deleted file mode 100644
index 4d6cd313c..000000000
--- a/wren-ai-service/src/pipelines/generation/intent_classification.py
+++ /dev/null
@@ -1,400 +0,0 @@
-import ast
-import logging
-import sys
-from typing import Any, Literal, Optional
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack import Document
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import DocumentStoreProvider, EmbedderProvider, LLMProvider
-from src.pipelines.common import build_table_ddl, clean_up_new_lines
-from src.pipelines.generation.utils.sql import construct_instructions
-from src.utils import trace_cost
-from src.web.v1.services import Configuration
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-intent_classification_system_prompt = """
-### Task ###
-You are an expert detective specializing in intent classification. Combine the user's current question and previous questions to determine their true intent based on the provided database schema. Classify the intent into one of these categories: `MISLEADING_QUERY`, `TEXT_TO_SQL`, `GENERAL`, or `USER_GUIDE`. Additionally, provide a concise reasoning (maximum 20 words) for your classification.
-
-### Instructions ###
-- **Follow the user's previous questions:** If there are previous questions, try to understand the user's current question as following the previous questions.
-- **Follow the user's instructions:** If there are instructions, strictly follow the instructions.
-- **Consider Context of Inputs:** Combine the user's current question, their previous questions, and the user's instructions together to identify the user's true intent.
-- **Rephrase Question:** Rewrite follow-up questions into full standalone questions using prior conversation context.
-- **Concise Reasoning:** The reasoning must be clear, concise, and limited to 20 words.
-- **Language Consistency:** Use the same language as specified in the user's output language for the rephrased question and reasoning.
-- **Vague Queries:** If the question is vague or does not related to a table or property from the schema, classify it as `MISLEADING_QUERY`.
-- **Incomplete Queries:** If the question is related to the database schema but references unspecified values (e.g., "the following", "these", "those") without providing them, classify as `GENERAL`.
-- **Time-related Queries:** Don't rephrase time-related information in the user's question.
-
-### Intent Definitions ###
-
-
-**When to Use:**
-- The user's inputs are about modifying SQL from previous questions.
-- The user's inputs are related to the database schema and requires an SQL query.
-- The question (or related previous query) includes references to specific tables, columns, or data details.
-- The question includes **complete information** with specific tables, columns, or data values needed for execution.
-- The question provides **all necessary parameters** to generate executable SQL.
-
-**Requirements:**
-- Must have complete filter criteria, specific values, or clear references to previous context.
-- Include specific table and column names from the schema in your reasoning or modifying SQL from previous questions.
-- Reference phrases from the user's inputs that clearly relate to the schema.
-
-**Examples:**
-- "What is the total sales for last quarter?"
-- "Show me all customers who purchased product X."
-- "List the top 10 products by revenue."
-
-
-
-**When to Use:**
-- The user seeks general information about the database schema or its overall capabilities.
-- The query references **missing information** (e.g., "the following items" without listing them).
-- The query contains **placeholder references** that cannot be resolved from context.
-- The query is **incomplete for SQL generation** despite mentioning database concepts.
-
-**Requirements:**
-- Incorporate phrases from the user's inputs that indicate incompleteness or lack of relevance to the database schema.
-- Identify missing parameters, unspecified references, or incomplete filter criteria.
-
-**Examples:**
-- "What is the dataset about?"
-- "Tell me more about the database."
-- "How can I analyze customer behavior with this data?"
-- "Show me orders for these products" (without specifying which products)
-- "Filter by the criteria I mentioned" (without previous context defining criteria)
-
-
-
-**When to Use:**
-- The user's inputs pertains to Wren AI's features, usage, or capabilities.
-- The query relates directly to content in the user guide.
-
-**Examples:**
-- "What can Wren AI do?"
-- "How can I reset a project?"
-- "How can I delete a project?"
-- "How can I connect to other databases?"
-- "How do I draw a chart?"
-
-
-
-**When to Use:**
-- The user's inputs is irrelevant to the database schema or includes SQL code.
-- The user's inputs lacks specific details (like table names or columns) needed to generate an SQL query.
-- It appears off-topic or is simply a casual conversation starter.
-
-**Requirements:**
-- Incorporate phrases from the user's inputs that indicate lack of relevance to the database schema.
-
-**Examples:**
-- "How are you?"
-- "What's the weather like today?"
-- "Tell me a joke."
-
-
-### Output Format ###
-Return your response as a JSON object with the following structure:
-
-{
- "rephrased_question": "",
- "reasoning": "",
- "results": "MISLEADING_QUERY" | "TEXT_TO_SQL" | "GENERAL" | "USER_GUIDE"
-}
-"""
-
-intent_classification_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for db_schema in db_schemas %}
- {{ db_schema }}
-{% endfor %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sql_sample in sql_samples %}
-Question:
-{{sql_sample.question}}
-SQL:
-{{sql_sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### USER GUIDE ###
-{% for doc in docs %}
-- {{doc.path}}: {{doc.content}}
-{% endfor %}
-
-### INPUT ###
-{% if histories %}
-User's previous questions:
-{% for history in histories %}
-Question:
-{{ history.question }}
-SQL:
-{{ history.sql }}
-{% endfor %}
-{% endif %}
-
-User's current question: {{query}}
-Output Language: {{ language }}
-
-Let's think step by step
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False, capture_output=False)
-async def embedding(query: str, embedder: Any, histories: list[AskHistory]) -> dict:
- previous_query_summaries = (
- [history.question for history in histories] if histories else []
- )
-
- query = "\n".join(previous_query_summaries) + "\n" + query
-
- return await embedder.run(query)
-
-
-@observe(capture_input=False)
-async def table_retrieval(
- embedding: dict, project_id: str, table_retriever: Any
-) -> dict:
- filters = {
- "operator": "AND",
- "conditions": [
- {"field": "type", "operator": "==", "value": "TABLE_DESCRIPTION"},
- ],
- }
-
- if project_id:
- filters["conditions"].append(
- {"field": "project_id", "operator": "==", "value": project_id}
- )
-
- return await table_retriever.run(
- query_embedding=embedding.get("embedding"),
- filters=filters,
- )
-
-
-@observe(capture_input=False)
-async def dbschema_retrieval(
- table_retrieval: dict, embedding: dict, project_id: str, dbschema_retriever: Any
-) -> list[Document]:
- tables = table_retrieval.get("documents", [])
- table_names = []
- for table in tables:
- content = ast.literal_eval(table.content)
- table_names.append(content["name"])
-
- logger.info(f"dbschema_retrieval with table_names: {table_names}")
-
- table_name_conditions = [
- {"field": "name", "operator": "==", "value": table_name}
- for table_name in table_names
- ]
-
- filters = {
- "operator": "AND",
- "conditions": [
- {"field": "type", "operator": "==", "value": "TABLE_SCHEMA"},
- {"operator": "OR", "conditions": table_name_conditions},
- ],
- }
-
- if project_id:
- filters["conditions"].append(
- {"field": "project_id", "operator": "==", "value": project_id}
- )
-
- results = await dbschema_retriever.run(
- query_embedding=embedding.get("embedding"), filters=filters
- )
- return results["documents"]
-
-
-@observe()
-def construct_db_schemas(dbschema_retrieval: list[Document]) -> list[str]:
- db_schemas = {}
- for document in dbschema_retrieval:
- content = ast.literal_eval(document.content)
- if content["type"] == "TABLE":
- if document.meta["name"] not in db_schemas:
- db_schemas[document.meta["name"]] = content
- else:
- db_schemas[document.meta["name"]] = {
- **content,
- "columns": db_schemas[document.meta["name"]].get("columns", []),
- }
- elif content["type"] == "TABLE_COLUMNS":
- if document.meta["name"] not in db_schemas:
- db_schemas[document.meta["name"]] = {"columns": content["columns"]}
- else:
- if "columns" not in db_schemas[document.meta["name"]]:
- db_schemas[document.meta["name"]]["columns"] = content["columns"]
- else:
- db_schemas[document.meta["name"]]["columns"] += content["columns"]
-
- # remove incomplete schemas
- db_schemas = {k: v for k, v in db_schemas.items() if "type" in v and "columns" in v}
-
- db_schemas_in_ddl = []
- for table_schema in list(db_schemas.values()):
- if table_schema["type"] == "TABLE":
- ddl, _, _ = build_table_ddl(table_schema)
- db_schemas_in_ddl.append(ddl)
-
- return db_schemas_in_ddl
-
-
-@observe(capture_input=False)
-def prompt(
- query: str,
- wren_ai_docs: list[dict],
- construct_db_schemas: list[str],
- histories: list[AskHistory],
- prompt_builder: PromptBuilder,
- sql_samples: Optional[list[dict]] = None,
- instructions: Optional[list[dict]] = None,
- configuration: Configuration | None = None,
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- language=configuration.language,
- db_schemas=construct_db_schemas,
- histories=histories,
- sql_samples=sql_samples,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- docs=wren_ai_docs,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def classify_intent(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def post_process(classify_intent: dict, construct_db_schemas: list[str]) -> dict:
- try:
- results = orjson.loads(classify_intent.get("replies")[0])
- return {
- "rephrased_question": results["rephrased_question"],
- "intent": results["results"],
- "reasoning": results["reasoning"],
- "db_schemas": construct_db_schemas,
- }
- except Exception:
- return {
- "rephrased_question": "",
- "intent": "TEXT_TO_SQL",
- "reasoning": "",
- "db_schemas": construct_db_schemas,
- }
-
-
-## End of Pipeline
-
-
-class IntentClassificationResult(BaseModel):
- rephrased_question: str
- results: Literal["MISLEADING_QUERY", "TEXT_TO_SQL", "GENERAL", "USER_GUIDE"]
- reasoning: str
-
-
-INTENT_CLASSIFICAION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "intent_classification",
- "schema": IntentClassificationResult.model_json_schema(),
- },
- }
-}
-
-
-class IntentClassification(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- embedder_provider: EmbedderProvider,
- document_store_provider: DocumentStoreProvider,
- wren_ai_docs: list[dict],
- table_retrieval_size: Optional[int] = 50,
- table_column_retrieval_size: Optional[int] = 100,
- **kwargs,
- ):
- self._components = {
- "embedder": embedder_provider.get_text_embedder(),
- "table_retriever": document_store_provider.get_retriever(
- document_store_provider.get_store(dataset_name="table_descriptions"),
- top_k=table_retrieval_size,
- ),
- "dbschema_retriever": document_store_provider.get_retriever(
- document_store_provider.get_store(),
- top_k=table_column_retrieval_size,
- ),
- "generator": llm_provider.get_generator(
- system_prompt=intent_classification_system_prompt,
- generation_kwargs=INTENT_CLASSIFICAION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=intent_classification_user_prompt_template
- ),
- }
-
- self._configs = {
- "wren_ai_docs": wren_ai_docs,
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Intent Classification")
- async def run(
- self,
- query: str,
- project_id: Optional[str] = None,
- histories: Optional[list[AskHistory]] = None,
- sql_samples: Optional[list[dict]] = None,
- instructions: Optional[list[dict]] = None,
- configuration: Configuration = Configuration(),
- ):
- logger.info("Intent Classification pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "project_id": project_id or "",
- "histories": histories or [],
- "sql_samples": sql_samples or [],
- "instructions": instructions or [],
- "configuration": configuration,
- **self._components,
- **self._configs,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/misleading_assistance.py b/wren-ai-service/src/pipelines/generation/misleading_assistance.py
deleted file mode 100644
index a35738ecf..000000000
--- a/wren-ai-service/src/pipelines/generation/misleading_assistance.py
+++ /dev/null
@@ -1,171 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-misleading_assistance_system_prompt = """
-### TASK ###
-You are a helpful assistant that can help users understand their data better. Currently, you are given a user's question that is potentially misleading.
-Your goal is to help guide user understand its data better and suggest few better questions to ask.
-
-### INSTRUCTIONS ###
-
-- Answer must be in the same language user specified in the Language section of the `### INPUT ###` section.
-- There should be proper line breaks, whitespace, and Markdown formatting(headers, lists, tables, etc.) in your response.
-- MUST NOT add SQL code in your response.
-- MUST consider database schema when suggesting better questions.
-- The maximum response length is 100 words.
-- If the user provides a custom instruction, it should be followed strictly and you should use it to change the style of response.
-
-### OUTPUT FORMAT ###
-Please provide your response in proper Markdown format without ```markdown``` tags.
-"""
-
-misleading_assistance_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for db_schema in db_schemas %}
- {{ db_schema }}
-{% endfor %}
-
-### INPUT ###
-User's question: {{query}}
-Language: {{language}}
-
-Custom Instruction: {{ custom_instruction }}
-
-Please think step by step
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- db_schemas: list[str],
- language: str,
- histories: list[AskHistory],
- prompt_builder: PromptBuilder,
- custom_instruction: str,
-) -> dict:
- previous_query_summaries = (
- [history.question for history in histories] if histories else []
- )
- query = "\n".join(previous_query_summaries) + "\n" + query
-
- _prompt = prompt_builder.run(
- query=query,
- db_schemas=db_schemas,
- language=language,
- custom_instruction=custom_instruction,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def misleading_assistance(
- prompt: dict, generator: Any, query_id: str, generator_name: str
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"),
- query_id=query_id,
- ), generator_name
-
-
-## End of Pipeline
-
-
-class MisleadingAssistance(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=misleading_assistance_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=misleading_assistance_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Create a new queue for the user if it doesn't exist
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Ensure the user's queue exists
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="Misleading Assistance")
- async def run(
- self,
- query: str,
- db_schemas: list[str],
- language: str,
- query_id: Optional[str] = None,
- histories: Optional[list[AskHistory]] = None,
- custom_instruction: Optional[str] = None,
- ):
- logger.info("Misleading Assistance pipeline is running...")
- return await self._pipe.execute(
- ["misleading_assistance"],
- inputs={
- "query": query,
- "db_schemas": db_schemas,
- "language": language,
- "query_id": query_id or "",
- "histories": histories or [],
- "custom_instruction": custom_instruction or "",
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/question_recommendation.py b/wren-ai-service/src/pipelines/generation/question_recommendation.py
deleted file mode 100644
index a6e7c17b0..000000000
--- a/wren-ai-service/src/pipelines/generation/question_recommendation.py
+++ /dev/null
@@ -1,278 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-system_prompt = """
-You are an expert in data analysis and SQL query generation. Given a data model specification, optionally a user's question, and a list of categories, your task is to generate insightful, specific questions that can be answered using the provided data model. Each question should be accompanied by a brief explanation of its relevance or importance.
-
-### JSON Output Structure
-
-Output all questions in the following JSON format:
-
-```json
-{
- "questions": [
- {
- "question": "",
- "category": ""
- },
- ...
- ]
-}
-```
-
-### Guidelines for Generating Questions
-
-1. **If Categories Are Provided:**
-
- - **Randomly select categories** from the list and ensure no single category dominates the output.
- - Ensure a balanced distribution of questions across all provided categories.
- - For each generated question, **randomize the category selection** to avoid a fixed order.
-
-2. **Incorporate Diverse Analysis Techniques:**
-
- - Use a mix of the following analysis techniques for each category:
- - **Drill-down:** Delve into detailed levels of data.
- - **Roll-up:** Aggregate data to higher levels.
- - **Slice and Dice:** Analyze data from different perspectives.
- - **Trend Analysis:** Identify patterns or changes over time.
- - **Comparative Analysis:** Compare segments, groups, or time periods.
-
-3. **If a User Question is Provided:**
-
- - Generate questions that are closely related to the user's previous question, ensuring that the new questions build upon or provide deeper insights into the original query.
- - Use **random category selection** to introduce diverse perspectives while maintaining a focus on the context of the previous question.
- - Apply the analysis techniques above to enhance the relevance and depth of the generated questions.
-
-4. **If No User Question is Provided:**
-
- - Ensure questions cover different aspects of the data model.
- - Randomly distribute questions across all categories to ensure variety.
-
-5. **General Guidelines for All Questions:**
- - Ensure questions can be answered using the data model.
- - Mix simple and complex questions.
- - Avoid open-ended questions - each should have a definite answer.
- - Incorporate time-based analysis where relevant.
- - Combine multiple analysis techniques when appropriate for deeper insights.
-
-### Categories of Questions
-
-1. **Descriptive Questions**
- Summarize historical data.
-
- - Example: _"What was the total sales volume for each product last quarter?"_
-
-2. **Segmentation Questions**
- Identify meaningful data segments.
-
- - Example: _"Which customer segments contributed most to revenue growth?"_
-
-3. **Comparative Questions**
- Compare data across segments or periods.
-
- - Example: _"How did Product A perform compared to Product B last year?"_
-
-4. **Data Quality/Accuracy Questions**
- Assess data reliability and completeness.
-
- - Example: _"Are there inconsistencies in the sales records for Q1?"_
-
----
-
-### Example JSON Output
-
-```json
-{
- "questions": [
- {
- "question": "What was the total revenue generated by each region in the last year?",
- "category": "Descriptive Questions"
- },
- {
- "question": "How do customer preferences differ between age groups?",
- "category": "Segmentation Questions"
- },
- {
- "question": "How does the conversion rate vary across different lead sources?",
- "category": "Comparative Questions"
- },
- {
- "question": "What percentage of contacts have incomplete or missing key properties (e.g., email, lifecycle stage, or deal association)",
- "category": "Data Quality/Accuracy Questions"
- }
- ]
-}
-```
-
----
-
-### Additional Instructions for Randomization
-
-- **Randomize Category Order:**
- Ensure that categories are selected in a random order for each question generation session.
-
-- **Avoid Repetition:**
- Ensure the same category doesn't dominate the list by limiting the number of questions from any single category unless specified otherwise.
-
-- **Diversity of Analysis:**
- Combine different analysis techniques (drill-down, roll-up, etc.) within the selected categories for richer insights.
-
-- **Shuffle Categories:**
- If possible, shuffle the list of categories internally before generating questions to ensure varied selection.
-
-
-"""
-
-user_prompt_template = """
-
-{% if previous_questions %}
-Previous Questions: {{previous_questions}}
-{% endif %}
-
-{% if categories %}
-Categories: {{categories}}
-{% endif %}
-
-{% if documents %}
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-{% endif %}
-
-Please generate {{max_questions}} insightful questions for each of the {{max_categories}} categories based on the provided data model. Both the questions and category names should be translated into {{language}}{% if user_question %} and be related to the user's question{% endif %}. The output format should maintain the structure but with localized text.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- previous_questions: list[str],
- documents: list,
- language: str,
- max_questions: int,
- max_categories: int,
- prompt_builder: PromptBuilder,
-) -> dict:
- """
- If previous_questions is provided, the MDL is omitted to allow the LLM to focus on
- generating recommendations based on the question history. This helps provide more
- contextually relevant questions that build on previous questions.
- """
-
- _prompt = prompt_builder.run(
- documents=documents,
- previous_questions=previous_questions,
- language=language,
- max_questions=max_questions,
- max_categories=max_categories,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def normalized(generate: dict) -> dict:
- def wrapper(text: str) -> list:
- text = text.replace("\n", " ")
- text = " ".join(text.split())
- try:
- text_list = orjson.loads(text.strip())
- return text_list
- except orjson.JSONDecodeError as e:
- logger.error(f"Error decoding JSON: {e}")
- return [] # Return an empty list if JSON decoding fails
-
- reply = generate.get("replies")[0] # Expecting only one reply
- normalized = wrapper(reply)
-
- return normalized
-
-
-## End of Pipeline
-class Question(BaseModel):
- question: str
- category: str
-
-
-class QuestionResult(BaseModel):
- questions: list[Question]
-
-
-QUESTION_RECOMMENDATION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "question_recommendation",
- "schema": QuestionResult.model_json_schema(),
- },
- }
-}
-
-
-class QuestionRecommendation(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **_,
- ):
- self._components = {
- "prompt_builder": PromptBuilder(template=user_prompt_template),
- "generator": llm_provider.get_generator(
- system_prompt=system_prompt,
- generation_kwargs=QUESTION_RECOMMENDATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- }
-
- self._final = "normalized"
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Question Recommendation")
- async def run(
- self,
- contexts: list[str],
- previous_questions: list[str] = [],
- categories: list[str] = [],
- language: str = "en",
- max_questions: int = 5,
- max_categories: int = 3,
- **_,
- ) -> dict:
- logger.info("Question Recommendation pipeline is running...")
- return await self._pipe.execute(
- [self._final],
- inputs={
- "documents": contexts,
- "previous_questions": previous_questions,
- "categories": categories,
- "language": language,
- "max_questions": max_questions,
- "max_categories": max_categories,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/relationship_recommendation.py b/wren-ai-service/src/pipelines/generation/relationship_recommendation.py
deleted file mode 100644
index e0d0bed67..000000000
--- a/wren-ai-service/src/pipelines/generation/relationship_recommendation.py
+++ /dev/null
@@ -1,236 +0,0 @@
-import logging
-import sys
-from enum import Enum
-from typing import Any
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-system_prompt = """
-You are an expert in database schema design and relationship recommendation. Given a data model specification that includes various models and their attributes, your task is to analyze the models and suggest appropriate relationships between them, but only if there are clear and beneficial relationships to recommend. For each valid relationship, provide the following details:
-
-- **name**: A descriptive name for the relationship.
-- **fromModel**: The name of the source model.
-- **fromColumn**: The column in the source model that forms the relationship.
-- **type**: The type of relationship, which can be "MANY_TO_ONE", "ONE_TO_MANY" or "ONE_TO_ONE" only.
-- **toModel**: The name of the target model.
-- **toColumn**: The column in the target model that forms the relationship.
-- **reason**: The reason for recommending this relationship.
-
-Important guidelines:
-1. Do not recommend relationships within the same model (fromModel and toModel must be different).
-2. Only suggest relationships if there is a clear and beneficial reason to do so.
-3. If there are no good relationships to recommend or if there are fewer than two models, return an empty list of relationships.
-4. Use "MANY_TO_ONE" and "ONE_TO_MANY" instead of "MANY_TO_MANY" relationships.
-
-Output all relationships in the following JSON structure:
-
-{
- "relationships": [
- {
- "name": "",
- "fromModel": "",
- "fromColumn": "",
- "type": "",
- "toModel": "",
- "toColumn": "",
- "reason": ""
- }
- ...
- ]
-}
-
-If no relationships are recommended, return:
-
-{
- "relationships": []
-}
-"""
-
-user_prompt_template = """
-Here is the relationship specification for my data model:
-
-{{models}}
-
-**Please analyze these models and suggest optimizations for their relationships.**
-Take into account best practices in database design, opportunities for normalization, indexing strategies, and any additional relationships that could improve data integrity and enhance query performance.
-
-Use this for the relationship name and reason based on the localization language: {{language}}
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def cleaned_models(mdl: dict) -> dict:
- def remove_display_name(d: dict) -> dict:
- if "properties" in d and isinstance(d["properties"], dict):
- d["properties"] = d["properties"].copy()
- d["properties"].pop("displayName", None)
- return d
-
- def column_filter(columns: list[dict]) -> list[dict]:
- filtered_columns = []
- for column in columns:
- if "relationship" not in column:
- # Create a copy of the column to avoid modifying the original
- filtered_column = column.copy()
- filtered_column = remove_display_name(filtered_column)
- filtered_columns.append(filtered_column)
- return filtered_columns
-
- return [
- remove_display_name(
- {**model, "columns": column_filter(model.get("columns", []))}
- )
- for model in mdl.get("models", [])
- ]
-
-
-@observe(capture_input=False)
-def prompt(
- cleaned_models: dict,
- prompt_builder: PromptBuilder,
- language: str,
-) -> dict:
- _prompt = prompt_builder.run(models=cleaned_models, language=language)
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def normalized(generate: dict) -> dict:
- def wrapper(text: str) -> str:
- text = text.replace("\n", " ")
- text = " ".join(text.split())
- # Convert the normalized text to a dictionary
- try:
- text_dict = orjson.loads(text.strip())
- return text_dict
- except orjson.JSONDecodeError as e:
- logger.error(f"Error decoding JSON: {e}")
- return {} # Return an empty dictionary if JSON decoding fails
-
- reply = generate.get("replies")[0] # Expecting only one reply
- normalized = wrapper(reply)
-
- return normalized
-
-
-@observe(capture_input=False)
-def validated(normalized: dict, mdl: dict) -> dict:
- model_columns = {
- model["name"]: set(
- [
- column["name"]
- for column in model.get("columns", [])
- if not column.get("relationship")
- ]
- )
- for model in mdl.get("models", [])
- }
-
- relationships = normalized.get("relationships", [])
- validated_relationships = [
- relationship
- for relationship in relationships
- if RelationType.is_include(relationship.get("type"))
- and relationship.get("fromModel") in model_columns
- and relationship.get("toModel") in model_columns
- and relationship.get("fromColumn")
- in model_columns.get(relationship.get("fromModel"))
- and relationship.get("toColumn")
- in model_columns.get(relationship.get("toModel"))
- ]
-
- return {"relationships": validated_relationships}
-
-
-## End of Pipeline
-class RelationType(Enum):
- MANY_TO_ONE = "MANY_TO_ONE"
- ONE_TO_MANY = "ONE_TO_MANY"
- ONE_TO_ONE = "ONE_TO_ONE"
-
- @classmethod
- def is_include(cls, value: str) -> bool:
- return value in cls._value2member_map_
-
-
-class ModelRelationship(BaseModel):
- name: str
- fromModel: str
- fromColumn: str
- type: RelationType
- toModel: str
- toColumn: str
- reason: str
-
-
-class RelationshipResult(BaseModel):
- relationships: list[ModelRelationship]
-
-
-RELATIONSHIP_RECOMMENDATION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "semantic_description",
- "schema": RelationshipResult.model_json_schema(),
- },
- }
-}
-
-
-class RelationshipRecommendation(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **_,
- ):
- self._components = {
- "prompt_builder": PromptBuilder(template=user_prompt_template),
- "generator": llm_provider.get_generator(
- system_prompt=system_prompt,
- generation_kwargs=RELATIONSHIP_RECOMMENDATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- }
-
- self._final = "validated"
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Relationship Recommendation")
- async def run(
- self,
- mdl: dict,
- language: str = "English",
- ) -> dict:
- logger.info("Relationship Recommendation pipeline is running...")
- return await self._pipe.execute(
- [self._final],
- inputs={
- "mdl": mdl,
- "language": language,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/semantics_description.py b/wren-ai-service/src/pipelines/generation/semantics_description.py
deleted file mode 100644
index acc5fc859..000000000
--- a/wren-ai-service/src/pipelines/generation/semantics_description.py
+++ /dev/null
@@ -1,253 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.indexing import clean_display_name
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-system_prompt = """
-I have a data model represented in JSON format, with the following structure:
-
-```
-[
- {'name': 'model', 'columns': [
- {'name': 'column_1', 'type': 'type', 'properties': {}
- },
- {'name': 'column_2', 'type': 'type', 'properties': {}
- },
- {'name': 'column_3', 'type': 'type', 'properties': {}
- }
- ], 'properties': {}
- }
-]
-```
-
-Your task is to update this JSON structure by adding a `description` field inside both the `properties` attribute of each `column` and the `model` itself.
-Each `description` should be derived from a user-provided input that explains the purpose or context of the `model` and its respective columns.
-Follow these steps:
-1. **For the `model`**: Prompt the user to provide a brief description of the model's overall purpose or its context. Insert this description in the `properties` field of the `model`.
-2. **For each `column`**: Ask the user to describe each column's role or significance. Each column's description should be added under its respective `properties` field in the format: `'description': 'user-provided text'`.
-3. Ensure that the output is a well-formatted JSON structure, preserving the input's original format and adding the appropriate `description` fields.
-
-### Output Format:
-
-```
-{
- "models": [
- {
- "name": "model",
- "columns": [
- {
- "name": "column_1",
- "properties": {
- "description": ""
- }
- },
- {
- "name": "column_2",
- "properties": {
- "description": ""
- }
- },
- {
- "name": "column_3",
- "properties": {
- "description": ""
- }
- }
- ],
- "properties": {
- "description": ""
- }
- }
- ]
-}
-```
-
-Make sure that the descriptions are concise, informative, and contextually appropriate based on the input provided by the user.
-"""
-
-user_prompt_template = """
-### Input:
-User's prompt: {{ user_prompt }}
-Picked models: {{ picked_models }}
-Localization Language: {{ language }}
-
-Please provide a brief description for the model and each column based on the user's prompt.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def picked_models(mdl: dict, selected_models: list[str]) -> list[dict]:
- def relation_filter(column: dict) -> bool:
- return "relationship" not in column
-
- def column_formatter(columns: list[dict]) -> list[dict]:
- return [
- {
- "name": column["name"],
- "type": column["type"],
- "properties": {
- "description": column["properties"].get("description", ""),
- "alias": clean_display_name(
- column["properties"].get("displayName", "")
- ),
- },
- }
- for column in columns
- if relation_filter(column)
- ]
-
- def extract(model: dict) -> dict:
- return {
- "name": model["name"],
- "columns": column_formatter(model["columns"]),
- "properties": {
- "description": model["properties"].get("description", ""),
- "alias": clean_display_name(model["properties"].get("displayName", "")),
- },
- }
-
- return [
- extract(model)
- for model in mdl.get("models", [])
- if model.get("name", "") in selected_models
- ]
-
-
-@observe(capture_input=False)
-def prompt(
- picked_models: list[dict],
- user_prompt: str,
- prompt_builder: PromptBuilder,
- language: str,
-) -> dict:
- _prompt = prompt_builder.run(
- picked_models=picked_models,
- user_prompt=user_prompt,
- language=language,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def normalize(generate: dict) -> dict:
- def wrapper(text: str) -> str:
- text = text.replace("\n", " ")
- text = " ".join(text.split())
- # Convert the normalized text to a dictionary
- try:
- text_dict = orjson.loads(text.strip())
- return text_dict
- except orjson.JSONDecodeError as e:
- logger.error(f"Error decoding JSON: {e}")
- return {"models": []} # Return an empty list if JSON decoding fails
-
- reply = generate.get("replies")[0] # Expecting only one reply
- normalized = wrapper(reply)
-
- return {model["name"]: model for model in normalized["models"]}
-
-
-@observe(capture_input=False)
-def output(normalize: dict, picked_models: list[dict]) -> dict:
- def _filter(enriched: list[dict], columns: list[dict]) -> list[dict]:
- valid_columns = [col["name"] for col in columns]
-
- return [col for col in enriched if col["name"] in valid_columns]
-
- models = {model["name"]: model for model in picked_models}
-
- return {
- name: {**data, "columns": _filter(data["columns"], models[name]["columns"])}
- for name, data in normalize.items()
- if name in models
- }
-
-
-## End of Pipeline
-class ModelProperties(BaseModel):
- description: str
-
-
-class ModelColumns(BaseModel):
- name: str
- properties: ModelProperties
-
-
-class SemanticModel(BaseModel):
- name: str
- columns: list[ModelColumns]
- properties: ModelProperties
-
-
-class SemanticResult(BaseModel):
- models: list[SemanticModel]
-
-
-SEMANTICS_DESCRIPTION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "semantic_description",
- "schema": SemanticResult.model_json_schema(),
- },
- }
-}
-
-
-class SemanticsDescription(BasicPipeline):
- def __init__(self, llm_provider: LLMProvider, **_):
- self._components = {
- "prompt_builder": PromptBuilder(template=user_prompt_template),
- "generator": llm_provider.get_generator(
- system_prompt=system_prompt,
- generation_kwargs=SEMANTICS_DESCRIPTION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- }
- self._final = "output"
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Semantics Description Generation")
- async def run(
- self,
- user_prompt: str,
- selected_models: list[str],
- mdl: dict,
- language: str = "en",
- ) -> dict:
- logger.info("Semantics Description Generation pipeline is running...")
- return await self._pipe.execute(
- [self._final],
- inputs={
- "user_prompt": user_prompt,
- "selected_models": selected_models,
- "mdl": mdl,
- "language": language,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_answer.py b/wren-ai-service/src/pipelines/generation/sql_answer.py
deleted file mode 100644
index 81289081b..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_answer.py
+++ /dev/null
@@ -1,173 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-from src.web.v1.services import Configuration
-
-logger = logging.getLogger("wren-ai-service")
-
-sql_to_answer_system_prompt = """
-### TASK
-
-You are a data analyst that great at answering non-technical user's questions based on the data, sql so that even non technical users can easily understand.
-Please answer the user's question in concise and clear manner in Markdown format.
-
-### INSTRUCTIONS
-
-1. Read the user's question and understand the user's intention.
-2. Read the sql and understand the data.
-3. Make sure the answer is aimed for non-technical users, so don't mention any technical terms such as SQL syntax.
-4. Generate a concise and clear answer in string format to answerthe user's question based on the data and sql.
-5. If answer is in list format, only list top few examples, and tell users there are more results omitted.
-6. Answer must be in the same language user specified.
-7. Do not include ```markdown or ``` in the answer.
-8. If the user provides a custom instruction, it should be followed strictly and you should use it to change the style of response.
-
-### OUTPUT FORMAT
-
-Please provide your response in proper Markdown stringformat.
-"""
-
-sql_to_answer_user_prompt_template = """
-### Inputs ###
-User's question: {{ query }}
-SQL: {{ sql }}
-Data:
-columns: {{ sql_data.columns }}
-rows: {{ sql_data.data }}
-Language: {{ language }}
-Current Time: {{ current_time }}
-
-Custom Instruction: {{ custom_instruction }}
-
-Please think step by step and answer the user's question.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- sql: str,
- sql_data: dict,
- language: str,
- current_time: str,
- custom_instruction: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- sql=sql,
- sql_data=sql_data,
- language=language,
- current_time=current_time,
- custom_instruction=custom_instruction,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_answer(
- prompt: dict, generator: Any, query_id: str, generator_name: str
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"), query_id=query_id
- ), generator_name
-
-
-## End of Pipeline
-
-
-class SQLAnswer(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "prompt_builder": PromptBuilder(
- template=sql_to_answer_user_prompt_template
- ),
- "generator": llm_provider.get_generator(
- system_prompt=sql_to_answer_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Create a new queue for the user if it doesn't exist
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Ensure the user's queue exists
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="SQL Answer Generation")
- async def run(
- self,
- query: str,
- sql: str,
- sql_data: dict,
- language: str,
- current_time: str = Configuration().show_current_time(),
- query_id: Optional[str] = None,
- custom_instruction: Optional[str] = None,
- ) -> dict:
- logger.info("Sql_Answer Generation pipeline is running...")
- return await self._pipe.execute(
- ["generate_answer"],
- inputs={
- "query": query,
- "sql": sql,
- "sql_data": sql_data,
- "language": language,
- "current_time": current_time,
- "query_id": query_id,
- "custom_instruction": custom_instruction or "",
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_correction.py b/wren-ai-service/src/pipelines/generation/sql_correction.py
deleted file mode 100644
index 973b8c69a..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_correction.py
+++ /dev/null
@@ -1,200 +0,0 @@
-import logging
-import sys
-from typing import Any, Dict, List
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack import Document
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.engine import Engine
-from src.core.pipeline import BasicPipeline
-from src.core.provider import DocumentStoreProvider, LLMProvider
-from src.pipelines.common import clean_up_new_lines, retrieve_metadata
-from src.pipelines.generation.utils.sql import (
- SQL_GENERATION_MODEL_KWARGS,
- SQLGenPostProcessor,
- construct_instructions,
- get_text_to_sql_rules,
-)
-from src.pipelines.retrieval.sql_functions import SqlFunction
-from src.pipelines.retrieval.sql_knowledge import SqlKnowledge
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-def get_sql_correction_system_prompt(sql_knowledge: SqlKnowledge | None = None) -> str:
- text_to_sql_rules = get_text_to_sql_rules(sql_knowledge)
-
- return f"""
-### TASK ###
-You are an ANSI SQL expert with exceptional logical thinking skills and debugging skills, you need to fix the syntactically incorrect ANSI SQL query.
-
-### SQL CORRECTION INSTRUCTIONS ###
-
-1. First, think hard about the error message, and figure out the root cause first(please use the DATABASE SCHEMA, SQL FUNCTIONS and USER INSTRUCTIONS to help you figure out the root cause).
-2. Then, generate the syntactically correct ANSI SQL query to correct the error.
-
-### SQL RULES ###
-Make sure you follow the SQL Rules strictly.
-
-{text_to_sql_rules}
-
-### FINAL ANSWER FORMAT ###
-The final answer must be in JSON format:
-
-{{
- "sql":
-}}
-"""
-
-
-sql_correction_user_prompt_template = """
-{% if documents %}
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-{% endif %}
-
-{% if sql_functions %}
-### SQL FUNCTIONS ###
-{% for function in sql_functions %}
-{{ function }}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### QUESTION ###
-SQL: {{ invalid_generation_result.sql }}
-Error Message: {{ invalid_generation_result.error }}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- documents: List[Document],
- invalid_generation_result: Dict,
- prompt_builder: PromptBuilder,
- instructions: list[dict] | None = None,
- sql_functions: list[SqlFunction] | None = None,
-) -> dict:
- _prompt = prompt_builder.run(
- documents=documents,
- invalid_generation_result=invalid_generation_result,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- sql_functions=sql_functions,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_correction(
- prompt: dict,
- generator: Any,
- generator_name: str,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- current_system_prompt = get_sql_correction_system_prompt(sql_knowledge)
- return await generator(
- prompt=prompt.get("prompt"), current_system_prompt=current_system_prompt
- ), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- generate_sql_correction: dict,
- post_processor: SQLGenPostProcessor,
- data_source: str,
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
-) -> dict:
- return await post_processor.run(
- generate_sql_correction.get("replies"),
- project_id=project_id,
- use_dry_plan=use_dry_plan,
- data_source=data_source,
- allow_dry_plan_fallback=allow_dry_plan_fallback,
- )
-
-
-## End of Pipeline
-
-
-class SQLCorrection(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- document_store_provider: DocumentStoreProvider,
- engine: Engine,
- **kwargs,
- ):
- self._retriever = document_store_provider.get_retriever(
- document_store_provider.get_store("project_meta")
- )
-
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=get_sql_correction_system_prompt(None),
- generation_kwargs=SQL_GENERATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_correction_user_prompt_template
- ),
- "post_processor": SQLGenPostProcessor(engine=engine),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="SQL Correction")
- async def run(
- self,
- contexts: List[Document],
- invalid_generation_result: Dict[str, str],
- instructions: list[dict] | None = None,
- sql_functions: list[SqlFunction] | None = None,
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- sql_knowledge: SqlKnowledge | None = None,
- ):
- logger.info("SQLCorrection pipeline is running...")
-
- if use_dry_plan:
- metadata = await retrieve_metadata(project_id or "", self._retriever)
- else:
- metadata = {}
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "invalid_generation_result": invalid_generation_result,
- "documents": contexts,
- "instructions": instructions,
- "sql_functions": sql_functions,
- "project_id": project_id,
- "use_dry_plan": use_dry_plan,
- "allow_dry_plan_fallback": allow_dry_plan_fallback,
- "data_source": metadata.get("data_source", "local_file"),
- "sql_knowledge": sql_knowledge,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_diagnosis.py b/wren-ai-service/src/pipelines/generation/sql_diagnosis.py
deleted file mode 100644
index 3f22b9d51..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_diagnosis.py
+++ /dev/null
@@ -1,158 +0,0 @@
-import logging
-import sys
-from typing import Any, List
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack import Document
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_diagnosis_system_prompt = """
-### TASK ###
-You are an ANSI SQL expert with exceptional logical thinking skills and debugging skills, you need to diagnose the issue with the given SQL query, error message and database schema.
-
-### SQL DIAGNOSIS INSTRUCTIONS ###
-
-1. First, think hard about the error message, and analyze the invalid SQL query to figure out the root cause and which part is incorrect.
-2. Then, map the incorrect part of the invalid SQL query to the corresponding part of the original SQL query.
-3. Then, return the reasoning behind the diagnosis.(You should give me the part of the original SQL query that is incorrect and the reason why it is incorrect)
-4. Reasoning should be in the language same as the language user provided in the INPUTS section.
-5. Reasoning should be concise and to the point and within 50 words.
-
-### FINAL ANSWER FORMAT ###
-The final answer must be in JSON format:
-
-{
- "reasoning":
-}
-"""
-
-sql_diagnosis_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-### INPUTS ###
-Original SQL:
-{{ original_sql }}
-
-Invalid SQL:
-{{ invalid_sql }}
-
-Error Message:
-{{ error_message }}
-
-Language: {{ language }}
-
-Please think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- documents: List[Document],
- original_sql: str,
- invalid_sql: str,
- error_message: str,
- language: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- _prompt = prompt_builder.run(
- documents=documents,
- original_sql=original_sql,
- invalid_sql=invalid_sql,
- error_message=error_message,
- language=language,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_diagnosis(
- prompt: dict, generator: Any, generator_name: str
-) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- generate_sql_diagnosis: dict,
-) -> str:
- return orjson.loads(generate_sql_diagnosis.get("replies")[0])
-
-
-## End of Pipeline
-
-
-class SqlDiagnosisResult(BaseModel):
- reasoning: str
-
-
-SQL_DIAGNOSIS_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "sql_diagnosis_result",
- "schema": SqlDiagnosisResult.model_json_schema(),
- },
- }
-}
-
-
-class SQLDiagnosis(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=sql_diagnosis_system_prompt,
- generation_kwargs=SQL_DIAGNOSIS_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_diagnosis_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="SQL Diagnosis")
- async def run(
- self,
- contexts: List[Document],
- original_sql: str,
- invalid_sql: str,
- error_message: str,
- language: str,
- ):
- logger.info("SQLDiagnosis pipeline is running...")
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "documents": contexts,
- "original_sql": original_sql,
- "invalid_sql": invalid_sql,
- "error_message": error_message,
- "language": language,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_generation.py b/wren-ai-service/src/pipelines/generation/sql_generation.py
deleted file mode 100644
index 1ee4952b3..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_generation.py
+++ /dev/null
@@ -1,233 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.engine import Engine
-from src.core.pipeline import BasicPipeline
-from src.core.provider import DocumentStoreProvider, LLMProvider
-from src.pipelines.common import clean_up_new_lines, retrieve_metadata
-from src.pipelines.generation.utils.sql import (
- SQL_GENERATION_MODEL_KWARGS,
- SQLGenPostProcessor,
- construct_instructions,
- get_calculated_field_instructions,
- get_json_field_instructions,
- get_metric_instructions,
- get_sql_generation_system_prompt,
-)
-from src.pipelines.retrieval.sql_functions import SqlFunction
-from src.pipelines.retrieval.sql_knowledge import SqlKnowledge
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_generation_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-{% if calculated_field_instructions %}
-{{ calculated_field_instructions }}
-{% endif %}
-
-{% if metric_instructions %}
-{{ metric_instructions }}
-{% endif %}
-
-{% if json_field_instructions %}
-{{ json_field_instructions }}
-{% endif %}
-
-{% if sql_functions %}
-### SQL FUNCTIONS ###
-{% for function in sql_functions %}
-{{ function }}
-{% endfor %}
-{% endif %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sample in sql_samples %}
-Question:
-{{sample.question}}
-SQL:
-{{sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### QUESTION ###
-User's Question: {{ query }}
-
-{% if sql_generation_reasoning %}
-### REASONING PLAN ###
-{{ sql_generation_reasoning }}
-{% endif %}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- documents: list[str],
- prompt_builder: PromptBuilder,
- sql_generation_reasoning: str | None = None,
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- documents=documents,
- sql_generation_reasoning=sql_generation_reasoning,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- calculated_field_instructions=(
- get_calculated_field_instructions(sql_knowledge)
- if has_calculated_field
- else ""
- ),
- metric_instructions=(
- get_metric_instructions(sql_knowledge) if has_metric else ""
- ),
- json_field_instructions=(
- get_json_field_instructions(sql_knowledge) if has_json_field else ""
- ),
- sql_samples=sql_samples,
- sql_functions=sql_functions,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql(
- prompt: dict,
- generator: Any,
- generator_name: str,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- current_system_prompt = get_sql_generation_system_prompt(sql_knowledge)
- return await generator(
- prompt=prompt.get("prompt"), current_system_prompt=current_system_prompt
- ), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- generate_sql: dict,
- post_processor: SQLGenPostProcessor,
- data_source: str,
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- allow_data_preview: bool = False,
-) -> dict:
- return await post_processor.run(
- generate_sql.get("replies"),
- project_id=project_id,
- use_dry_plan=use_dry_plan,
- data_source=data_source,
- allow_dry_plan_fallback=allow_dry_plan_fallback,
- allow_data_preview=allow_data_preview,
- )
-
-
-## End of Pipeline
-
-
-class SQLGeneration(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- document_store_provider: DocumentStoreProvider,
- engine: Engine,
- **kwargs,
- ):
- self._retriever = document_store_provider.get_retriever(
- document_store_provider.get_store("project_meta")
- )
-
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=get_sql_generation_system_prompt(None),
- generation_kwargs=SQL_GENERATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_generation_user_prompt_template
- ),
- "post_processor": SQLGenPostProcessor(engine=engine),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="SQL Generation")
- async def run(
- self,
- query: str,
- contexts: list[str],
- sql_generation_reasoning: str | None = None,
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- project_id: str | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- allow_data_preview: bool = False,
- sql_knowledge: SqlKnowledge | None = None,
- ):
- logger.info("SQL Generation pipeline is running...")
-
- if use_dry_plan:
- metadata = await retrieve_metadata(project_id or "", self._retriever)
- else:
- metadata = {}
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "documents": contexts,
- "sql_generation_reasoning": sql_generation_reasoning,
- "sql_samples": sql_samples,
- "instructions": instructions,
- "project_id": project_id,
- "has_calculated_field": has_calculated_field,
- "has_metric": has_metric,
- "has_json_field": has_json_field,
- "sql_functions": sql_functions,
- "use_dry_plan": use_dry_plan,
- "allow_dry_plan_fallback": allow_dry_plan_fallback,
- "data_source": metadata.get("data_source", "local_file"),
- "allow_data_preview": allow_data_preview,
- "sql_knowledge": sql_knowledge,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_generation_reasoning.py b/wren-ai-service/src/pipelines/generation/sql_generation_reasoning.py
deleted file mode 100644
index 00b731cb2..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_generation_reasoning.py
+++ /dev/null
@@ -1,176 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.generation.utils.sql import (
- construct_instructions,
- sql_generation_reasoning_system_prompt,
-)
-from src.utils import trace_cost
-from src.web.v1.services import Configuration
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_generation_reasoning_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sql_sample in sql_samples %}
-Question:
-{{sql_sample.question}}
-SQL:
-{{sql_sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### INPUTS ###
-User's Question: {{ query }}
-Language: {{ language }}
-Current Time: {{ current_time }}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- documents: list[str],
- sql_samples: list[dict],
- instructions: list[dict],
- prompt_builder: PromptBuilder,
- configuration: Configuration | None = Configuration(),
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- documents=documents,
- sql_samples=sql_samples,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- language=configuration.language,
- current_time=configuration.show_current_time(),
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_reasoning(
- prompt: dict, generator: Any, query_id: str, generator_name: str
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"), query_id=query_id
- ), generator_name
-
-
-@observe()
-def post_process(
- generate_sql_reasoning: dict,
-) -> dict:
- return generate_sql_reasoning.get("replies")[0]
-
-
-## End of Pipeline
-
-
-class SQLGenerationReasoning(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=sql_generation_reasoning_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_generation_reasoning_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[query_id] = asyncio.Queue()
-
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[query_id] = asyncio.Queue()
-
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="SQL Generation Reasoning")
- async def run(
- self,
- query: str,
- contexts: list[str],
- sql_samples: Optional[list[dict]] = None,
- instructions: Optional[list[str]] = None,
- configuration: Configuration = Configuration(),
- query_id: Optional[str] = None,
- ):
- logger.info("SQL Generation Reasoning pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "query": query,
- "documents": contexts,
- "sql_samples": sql_samples or [],
- "instructions": instructions or [],
- "configuration": configuration,
- "query_id": query_id,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_question.py b/wren-ai-service/src/pipelines/generation/sql_question.py
deleted file mode 100644
index 81f3d3e62..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_question.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-from src.web.v1.services import Configuration
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_question_system_prompt = """
-### TASK ###
-
-You are a data analyst great at translating any SQL query into a question that can be answered by the given SQL query.
-
-### INSTRUCTIONS ###
-
-- The question should be in the language of the user provided
-- The question should be a single sentence, concise, and easy to understand
-
-### OUTPUT FORMAT ###
-
-Please return the result in the following JSON format:
-
-{
- "question":
-}
-"""
-
-sql_question_user_prompt_template = """
-SQL: {{sql}}
-Language: {{language}}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- sql: str,
- language: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- _prompt = prompt_builder.run(
- sql=sql,
- language=language,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def generate_sql_question(
- prompt: dict, generator: Any, generator_name: str
-) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-def post_process(
- generate_sql_question: dict,
-) -> str:
- return orjson.loads(generate_sql_question.get("replies")[0])["question"]
-
-
-## End of Pipeline
-
-
-class SQLQuestionResult(BaseModel):
- question: str
-
-
-SQL_QUESTION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "sql_question_result",
- "schema": SQLQuestionResult.model_json_schema(),
- },
- }
-}
-
-
-class SQLQuestion(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=sql_question_system_prompt,
- generation_kwargs=SQL_QUESTION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(template=sql_question_user_prompt_template),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Sql Question Generation")
- async def run(
- self,
- sql: str,
- configuration: Configuration = Configuration(),
- ):
- logger.info("Sql Question Generation pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "sql": sql,
- "language": configuration.language or "English",
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_regeneration.py b/wren-ai-service/src/pipelines/generation/sql_regeneration.py
deleted file mode 100644
index 4b7284aa2..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_regeneration.py
+++ /dev/null
@@ -1,227 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.engine import Engine
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.pipelines.generation.utils.sql import (
- SQL_GENERATION_MODEL_KWARGS,
- SQLGenPostProcessor,
- construct_instructions,
- get_calculated_field_instructions,
- get_json_field_instructions,
- get_metric_instructions,
- get_text_to_sql_rules,
-)
-from src.pipelines.retrieval.sql_functions import SqlFunction
-from src.pipelines.retrieval.sql_knowledge import SqlKnowledge
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-def get_sql_regeneration_system_prompt(
- sql_knowledge: SqlKnowledge | None = None,
-) -> str:
- text_to_sql_rules = get_text_to_sql_rules(sql_knowledge)
-
- return f"""
-### TASK ###
-You are a great ANSI SQL expert. Now you are given database schema, SQL generation reasoning and an original SQL query,
-please carefully review the reasoning, and then generate a new SQL query that matches the reasoning.
-While generating the new SQL query, you should use the original SQL query as a reference.
-While generating the new SQL query, make sure to use the database schema to generate the SQL query.
-
-{text_to_sql_rules}
-
-### FINAL ANSWER FORMAT ###
-The final answer must be a ANSI SQL query in JSON format:
-
-{{
- "sql":
-}}
-"""
-
-
-sql_regeneration_user_prompt_template = """
-### DATABASE SCHEMA ###
-{% for document in documents %}
- {{ document }}
-{% endfor %}
-
-{% if calculated_field_instructions %}
-{{ calculated_field_instructions }}
-{% endif %}
-
-{% if metric_instructions %}
-{{ metric_instructions }}
-{% endif %}
-
-{% if json_field_instructions %}
-{{ json_field_instructions }}
-{% endif %}
-
-{% if sql_functions %}
-### SQL FUNCTIONS ###
-{% for function in sql_functions %}
-{{ function }}
-{% endfor %}
-{% endif %}
-
-{% if sql_samples %}
-### SQL SAMPLES ###
-{% for sample in sql_samples %}
-Question:
-{{sample.question}}
-SQL:
-{{sample.sql}}
-{% endfor %}
-{% endif %}
-
-{% if instructions %}
-### USER INSTRUCTIONS ###
-{% for instruction in instructions %}
-{{ loop.index }}. {{ instruction }}
-{% endfor %}
-{% endif %}
-
-### QUESTION ###
-SQL generation reasoning: {{ sql_generation_reasoning }}
-Original SQL query: {{ sql }}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- documents: list[str],
- sql_generation_reasoning: str,
- sql: str,
- prompt_builder: PromptBuilder,
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- _prompt = prompt_builder.run(
- sql=sql,
- documents=documents,
- sql_generation_reasoning=sql_generation_reasoning,
- instructions=construct_instructions(
- instructions=instructions,
- ),
- calculated_field_instructions=(
- get_calculated_field_instructions(sql_knowledge)
- if has_calculated_field
- else ""
- ),
- metric_instructions=(
- get_metric_instructions(sql_knowledge) if has_metric else ""
- ),
- json_field_instructions=(
- get_json_field_instructions(sql_knowledge) if has_json_field else ""
- ),
- sql_samples=sql_samples,
- sql_functions=sql_functions,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def regenerate_sql(
- prompt: dict,
- generator: Any,
- generator_name: str,
- sql_knowledge: SqlKnowledge | None = None,
-) -> dict:
- current_system_prompt = get_sql_regeneration_system_prompt(sql_knowledge)
- return await generator(
- prompt=prompt.get("prompt"), current_system_prompt=current_system_prompt
- ), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- regenerate_sql: dict,
- post_processor: SQLGenPostProcessor,
- project_id: str | None = None,
-) -> dict:
- return await post_processor.run(
- regenerate_sql.get("replies"),
- project_id=project_id,
- )
-
-
-## End of Pipeline
-
-
-class SQLRegeneration(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- engine: Engine,
- **kwargs,
- ):
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=get_sql_regeneration_system_prompt(None),
- generation_kwargs=SQL_GENERATION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_regeneration_user_prompt_template
- ),
- "post_processor": SQLGenPostProcessor(engine=engine),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="SQL Regeneration")
- async def run(
- self,
- contexts: list[str],
- sql_generation_reasoning: str,
- sql: str,
- sql_samples: list[dict] | None = None,
- instructions: list[dict] | None = None,
- project_id: str | None = None,
- has_calculated_field: bool = False,
- has_metric: bool = False,
- has_json_field: bool = False,
- sql_functions: list[SqlFunction] | None = None,
- sql_knowledge: SqlKnowledge | None = None,
- ):
- logger.info("SQL Regeneration pipeline is running...")
-
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "documents": contexts,
- "sql_generation_reasoning": sql_generation_reasoning,
- "sql": sql,
- "sql_samples": sql_samples,
- "instructions": instructions,
- "project_id": project_id,
- "has_calculated_field": has_calculated_field,
- "has_metric": has_metric,
- "has_json_field": has_json_field,
- "sql_functions": sql_functions,
- "sql_knowledge": sql_knowledge,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/sql_tables_extraction.py b/wren-ai-service/src/pipelines/generation/sql_tables_extraction.py
deleted file mode 100644
index 7060e750b..000000000
--- a/wren-ai-service/src/pipelines/generation/sql_tables_extraction.py
+++ /dev/null
@@ -1,132 +0,0 @@
-import logging
-import sys
-from typing import Any
-
-import orjson
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-from pydantic import BaseModel
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-sql_tables_extraction_system_prompt = """
-### TASK ###
-
-You are a data analyst great at extracting a list of tables from any SQL query.
-
-### EXAMPLES ###
-
-SQL: SELECT * FROM table1
-Output: {
- "tables": ["table1"]
-}
-
-SQL: SELECT * FROM table1, table2
-Output: {
- "tables": ["table1", "table2"]
-}
-
-SQL: SELECT * FROM table1 JOIN table2 ON table1.id = table2.id
-Output: {
- "tables": ["table1", "table2"]
-}
-
-### OUTPUT FORMAT ###
-
-Please return the result in the following JSON format:
-
-{
- "tables":
-}
-"""
-
-sql_tables_extraction_user_prompt_template = """
-SQL: {{sql}}
-
-Let's think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- sql: str,
- prompt_builder: PromptBuilder,
-) -> dict:
- _prompt = prompt_builder.run(sql=sql)
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def extract_sql_tables(prompt: dict, generator: Any, generator_name: str) -> dict:
- return await generator(prompt=prompt.get("prompt")), generator_name
-
-
-@observe(capture_input=False)
-async def post_process(
- extract_sql_tables: dict,
-) -> list[str]:
- return orjson.loads(extract_sql_tables.get("replies")[0])["tables"]
-
-
-## End of Pipeline
-
-
-class SQLTablesExtractionResult(BaseModel):
- tables: list[str]
-
-
-SQL_TABLES_EXTRACTION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "sql_tables_extraction_result",
- "schema": SQLTablesExtractionResult.model_json_schema(),
- },
- }
-}
-
-
-class SQLTablesExtraction(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- **kwargs,
- ):
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=sql_tables_extraction_system_prompt,
- generation_kwargs=SQL_TABLES_EXTRACTION_MODEL_KWARGS,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=sql_tables_extraction_user_prompt_template
- ),
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- @observe(name="Sql Tables Extraction")
- async def run(
- self,
- sql: str,
- ):
- logger.info("Sql Tables Extraction pipeline is running...")
- return await self._pipe.execute(
- ["post_process"],
- inputs={
- "sql": sql,
- **self._components,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/user_guide_assistance.py b/wren-ai-service/src/pipelines/generation/user_guide_assistance.py
deleted file mode 100644
index be437f883..000000000
--- a/wren-ai-service/src/pipelines/generation/user_guide_assistance.py
+++ /dev/null
@@ -1,160 +0,0 @@
-import asyncio
-import logging
-import sys
-from typing import Any, Optional
-
-from hamilton import base
-from hamilton.async_driver import AsyncDriver
-from haystack.components.builders.prompt_builder import PromptBuilder
-from langfuse.decorators import observe
-
-from src.core.pipeline import BasicPipeline
-from src.core.provider import LLMProvider
-from src.pipelines.common import clean_up_new_lines
-from src.utils import trace_cost
-
-logger = logging.getLogger("wren-ai-service")
-
-
-user_guide_assistance_system_prompt = """
-You are a helpful assistant that can help users understand Wren AI.
-You are given a user question and a user guide.
-You need to understand the user question and the user guide, and then answer the user question.
-
-### INSTRUCTIONS ###
-1. Your answer should be in the same language as the language user provided.
-2. You must follow the user guide to answer the user question.
-3. If you think you cannot answer the user question given the user guide, please kindly respond user that you don't find relevant answer in the user guide.
-4. You should add citations to the user guide(document url) in your answer.
-5. You should provide your answer in Markdown format.
-6. If the user provides a custom instruction, it should be followed strictly and you should use it to change the style of response.
-
-### OUTPUT FORMAT ###
-Please provide your response in proper Markdown format without ```markdown``` tags.
-"""
-
-user_guide_assistance_user_prompt_template = """
-User Question: {{query}}
-Language: {{language}}
-User Guide:
-{% for doc in docs %}
-- {{doc.path}}: {{doc.content}}
-{% endfor %}
-
-Custom Instruction: {{ custom_instruction }}
-
-Please think step by step.
-"""
-
-
-## Start of Pipeline
-@observe(capture_input=False)
-def prompt(
- query: str,
- language: str,
- wren_ai_docs: list[dict],
- prompt_builder: PromptBuilder,
- custom_instruction: str,
-) -> dict:
- _prompt = prompt_builder.run(
- query=query,
- language=language,
- docs=wren_ai_docs,
- custom_instruction=custom_instruction,
- )
- return {"prompt": clean_up_new_lines(_prompt.get("prompt"))}
-
-
-@observe(as_type="generation", capture_input=False)
-@trace_cost
-async def user_guide_assistance(
- prompt: dict, generator: Any, query_id: str, generator_name: str
-) -> dict:
- return await generator(
- prompt=prompt.get("prompt"), query_id=query_id
- ), generator_name
-
-
-## End of Pipeline
-
-
-class UserGuideAssistance(BasicPipeline):
- def __init__(
- self,
- llm_provider: LLMProvider,
- wren_ai_docs: list[dict],
- **kwargs,
- ):
- self._user_queues = {}
- self._components = {
- "generator": llm_provider.get_generator(
- system_prompt=user_guide_assistance_system_prompt,
- streaming_callback=self._streaming_callback,
- ),
- "generator_name": llm_provider.get_model(),
- "prompt_builder": PromptBuilder(
- template=user_guide_assistance_user_prompt_template
- ),
- }
- self._configs = {
- "wren_ai_docs": wren_ai_docs,
- }
-
- super().__init__(
- AsyncDriver({}, sys.modules[__name__], result_builder=base.DictResult())
- )
-
- def _streaming_callback(self, chunk, query_id):
- if query_id not in self._user_queues:
- self._user_queues[
- query_id
- ] = asyncio.Queue() # Create a new queue for the user if it doesn't exist
- # Put the chunk content into the user's queue
- asyncio.create_task(self._user_queues[query_id].put(chunk.content))
- if chunk.meta.get("finish_reason"):
- asyncio.create_task(self._user_queues[query_id].put(""))
-
- async def get_streaming_results(self, query_id):
- async def _get_streaming_results(query_id):
- return await self._user_queues[query_id].get()
-
- if query_id not in self._user_queues:
- self._user_queues[query_id] = asyncio.Queue()
-
- while True:
- try:
- # Wait for an item from the user's queue
- self._streaming_results = await asyncio.wait_for(
- _get_streaming_results(query_id), timeout=120
- )
- if (
- self._streaming_results == ""
- ): # Check for end-of-stream signal
- del self._user_queues[query_id]
- break
- if self._streaming_results: # Check if there are results to yield
- yield self._streaming_results
- self._streaming_results = "" # Clear after yielding
- except TimeoutError:
- break
-
- @observe(name="User Guide Assistance")
- async def run(
- self,
- query: str,
- language: str,
- query_id: Optional[str] = None,
- custom_instruction: Optional[str] = None,
- ):
- logger.info("User Guide Assistance pipeline is running...")
- return await self._pipe.execute(
- ["user_guide_assistance"],
- inputs={
- "query": query,
- "language": language,
- "query_id": query_id or "",
- "custom_instruction": custom_instruction or "",
- **self._components,
- **self._configs,
- },
- )
diff --git a/wren-ai-service/src/pipelines/generation/utils/chart.py b/wren-ai-service/src/pipelines/generation/utils/chart.py
deleted file mode 100644
index 5d06b949a..000000000
--- a/wren-ai-service/src/pipelines/generation/utils/chart.py
+++ /dev/null
@@ -1,480 +0,0 @@
-import logging
-from typing import Any, Dict, Literal, Optional
-
-import orjson
-import pandas as pd
-from haystack import component
-from jsonschema import validate
-from jsonschema.exceptions import ValidationError
-from pydantic import BaseModel, Field
-
-logger = logging.getLogger("wren-ai-service")
-
-
-chart_generation_instructions = """
-### INSTRUCTIONS ###
-
-- Chart types: Bar chart, Line chart, Multi line chart, Area chart, Pie chart, Stacked bar chart, Grouped bar chart
-- You can only use the chart types provided in the instructions
-- Generated chart should answer the user's question and based on the semantics of the SQL query, and the sample data, sample column values are used to help you generate the suitable chart type
-- If the sample data is not suitable for visualization, you must return an empty string for the schema and chart type
-- If the sample data is empty, you must return an empty string for the schema and chart type
-- The language for the chart and reasoning must be the same language provided by the user
-- Please use the current time provided by the user to generate the chart
-- In order to generate the grouped bar chart, you need to follow the given instructions:
- - Disable Stacking: Add "stack": null to the y-encoding.
- - Use xOffset for subcategories to group bars.
- - Don't use "transform" section.
-- In order to generate the pie chart, you need to follow the given instructions:
- - Add {"type": "arc"} to the mark section.
- - Add "theta" encoding to the encoding section.
- - Add "color" encoding to the encoding section.
- - Don't add "innerRadius" to the mark section.
-- If the x-axis of the chart is a temporal field, the time unit should be the same as the question user asked.
- - For yearly question, the time unit should be "year".
- - For monthly question, the time unit should be "yearmonth".
- - For weekly question, the time unit should be "yearmonthdate".
- - For daily question, the time unit should be "yearmonthdate".
- - Default time unit is "yearmonth".
-- For each axis, generate the corresponding human-readable title based on the language provided by the user.
-- Make sure all of the fields(x, y, xOffset, color, etc.) in the encoding section of the chart schema are present in the column names of the data.
-
-### GUIDELINES TO PLOT CHART ###
-
-1. Understanding Your Data Types
-- Nominal (Categorical): Names or labels without a specific order (e.g., types of fruits, countries).
-- Ordinal: Categorical data with a meaningful order but no fixed intervals (e.g., rankings, satisfaction levels).
-- Quantitative: Numerical values representing counts or measurements (e.g., sales figures, temperatures).
-- Temporal: Date or time data (e.g., timestamps, dates).
-2. Chart Types and When to Use Them
-- Bar Chart
- - Use When: Comparing quantities across different categories.
- - Data Requirements:
- - One categorical variable (x-axis).
- - One quantitative variable (y-axis).
- - Example: Comparing sales numbers for different product categories.
-- Grouped Bar Chart
- - Use When: Comparing sub-categories within main categories.
- - Data Requirements:
- - Two categorical variables (x-axis grouped by one, color-coded by another).
- - One quantitative variable (y-axis).
- - Example: Sales numbers for different products across various regions.
-- Line Chart
- - Use When: Displaying trends over continuous data, especially time.
- - Data Requirements:
- - One temporal or ordinal variable (x-axis).
- - One quantitative variable (y-axis).
- - Example: Tracking monthly revenue over a year.
-- Multi Line Chart
- - Use When: Displaying trends over continuous data, especially time.
- - Data Requirements:
- - One temporal or ordinal variable (x-axis).
- - Two or more quantitative variables (y-axis and color).
- - Implementation Notes:
- - Uses `transform` with `fold` to combine multiple metrics into a single series
- - The folded metrics are distinguished using the color encoding
- - Example: Tracking monthly click rate and read rate over a year.
-- Area Chart
- - Use When: Similar to line charts but emphasizing the volume of change over time.
- - Data Requirements:
- - Same as Line Chart.
- - Example: Visualizing cumulative rainfall over months.
-- Pie Chart
- - Use When: Showing parts of a whole as percentages.
- - Data Requirements:
- - One categorical variable.
- - One quantitative variable representing proportions.
- - Example: Market share distribution among companies.
-- Stacked Bar Chart
- - Use When: Showing composition and comparison across categories.
- - Data Requirements: Same as grouped bar chart.
- - Example: Sales by region and product type.
-- Guidelines for Selecting Chart Types
- - Comparing Categories:
- - Bar Chart: Best for simple comparisons across categories.
- - Grouped Bar Chart: Use when you have sub-categories.
- - Stacked Bar Chart: Use to show composition within categories.
- - Showing Trends Over Time:
- - Line Chart: Ideal for continuous data over time.
- - Area Chart: Use when you want to emphasize volume or total value over time.
- - Displaying Proportions:
- - Pie Chart: Use for simple compositions at a single point in time.
- - Stacked Bar Chart (100%): Use for comparing compositions across multiple categories.
-
-### EXAMPLES ###
-
-1. Bar Chart
-- Sample Data:
- [
- {"Region": "North", "Sales": 100},
- {"Region": "South", "Sales": 200},
- {"Region": "East", "Sales": 300},
- {"Region": "West", "Sales": 400}
-]
-- Chart Schema:
-{
- "title": ,
- "mark": {"type": "bar"},
- "encoding": {
- "x": {"field": "Region", "type": "nominal", "title": },
- "y": {"field": "Sales", "type": "quantitative", "title": },
- "color": {"field": "Region", "type": "nominal", "title": ""}
- }
-}
-2. Line Chart
-- Sample Data:
-[
- {"Date": "2022-01-01", "Sales": 100},
- {"Date": "2022-01-02", "Sales": 200},
- {"Date": "2022-01-03", "Sales": 300},
- {"Date": "2022-01-04", "Sales": 400}
-]
-- Chart Schema:
-{
- "title": ,
- "mark": {"type": "line"},
- "encoding": {
- "x": {"field": "Date", "type": "temporal", "title": },
- "y": {"field": "Sales", "type": "quantitative", "title": }
- }
-}
-3. Pie Chart
-- Sample Data:
-[
- {"Company": "Company A", "Market Share": 0.4},
- {"Company": "Company B", "Market Share": 0.3},
- {"Company": "Company C", "Market Share": 0.2},
- {"Company": "Company D", "Market Share": 0.1}
-]
-- Chart Schema:
-{
- "title": ,
- "mark": {"type": "arc"},
- "encoding": {
- "theta": {"field": "Market Share", "type": "quantitative"},
- "color": {"field": "Company", "type": "nominal", "title": }
- }
-}
-4. Area Chart
-- Sample Data:
-[
- {"Date": "2022-01-01", "Sales": 100},
- {"Date": "2022-01-02", "Sales": 200},
- {"Date": "2022-01-03", "Sales": 300},
- {"Date": "2022-01-04", "Sales": 400}
-]
-- Chart Schema:
-{
- "title": "",
- "mark": {"type": "area"},
- "encoding": {
- "x": {"field": "Date", "type": "temporal", "title": ""},
- "y": {"field": "Sales", "type": "quantitative", "title": ""}
- }
-}
-5. Stacked Bar Chart
-- Sample Data:
-[
- {"Region": "North", "Product": "A", "Sales": 100},
- {"Region": "North", "Product": "B", "Sales": 150},
- {"Region": "South", "Product": "A", "Sales": 200},
- {"Region": "South", "Product": "B", "Sales": 250},
- {"Region": "East", "Product": "A", "Sales": 300},
- {"Region": "East", "Product": "B", "Sales": 350},
- {"Region": "West", "Product": "A", "Sales": 400},
- {"Region": "West", "Product": "B", "Sales": 450}
-]
-- Chart Schema:
-{
- "title": "",
- "mark": {"type": "bar"},
- "encoding": {
- "x": {"field": "Region", "type": "nominal", "title": ""},
- "y": {"field": "Sales", "type": "quantitative", "title": "", "stack": "zero"},
- "color": {"field": "Product", "type": "nominal", "title": ""}
- }
-}
-6. Grouped Bar Chart
-- Sample Data:
-[
- {"Region": "North", "Product": "A", "Sales": 100},
- {"Region": "North", "Product": "B", "Sales": 150},
- {"Region": "South", "Product": "A", "Sales": 200},
- {"Region": "South", "Product": "B", "Sales": 250},
- {"Region": "East", "Product": "A", "Sales": 300},
- {"Region": "East", "Product": "B", "Sales": 350},
- {"Region": "West", "Product": "A", "Sales": 400},
- {"Region": "West", "Product": "B", "Sales": 450}
-]
-- Chart Schema:
-{
- "title": "",
- "mark": {"type": "bar"},
- "encoding": {
- "x": {"field": "Region", "type": "nominal", "title": ""},
- "y": {"field": "Sales", "type": "quantitative", "title": ""},
- "xOffset": {"field": "Product", "type": "nominal", "title": ""},
- "color": {"field": "Product", "type": "nominal", "title": ""}
- }
-}
-7. Multi Line Chart
-- Sample Data:
-[
- {"Date": "2022-01-01", "readCount": 100, "clickCount": 10},
- {"Date": "2022-01-02", "readCount": 200, "clickCount": 30},
- {"Date": "2022-01-03", "readCount": 300, "clickCount": 20},
- {"Date": "2022-01-04", "readCount": 400, "clickCount": 40}
-]
-- Chart Schema:
-{
- "title": ,
- "mark": {"type": "line"},
- "transform": [
- {
- "fold": ["readCount", "clickCount"],
- "as": ["Metric", "Value"]
- }
- ],
- "encoding": {
- "x": {"field": "Date", "type": "temporal", "title": },
- "y": {"field": "Value", "type": "quantitative", "title": },
- "color": {"field": "Metric", "type": "nominal", "title": }
- }
-}
-"""
-
-
-@component
-class ChartDataPreprocessor:
- @component.output_types(
- sample_data=list[dict],
- sample_column_values=dict[str, Any],
- )
- def run(
- self,
- data: Dict[str, Any],
- sample_data_count: int = 15,
- sample_column_size: int = 5,
- ):
- columns = [
- column.get("name", "") if isinstance(column, dict) else column
- for column in data.get("columns", [])
- ]
- data = data.get("data", [])
-
- df = pd.DataFrame(data, columns=columns)
- sample_column_values = {
- col: list(df[col].unique())[:sample_column_size] for col in df.columns
- }
-
- if len(df) > sample_data_count:
- sample_data = df.sample(n=sample_data_count).to_dict(orient="records")
- else:
- sample_data = df.to_dict(orient="records")
-
- return {
- "sample_data": sample_data,
- "sample_column_values": sample_column_values,
- }
-
-
-@component
-class ChartGenerationPostProcessor:
- @component.output_types(
- results=Dict[str, Any],
- )
- def run(
- self,
- replies: str,
- vega_schema: Dict[str, Any],
- sample_data: list[dict],
- remove_data_from_chart_schema: Optional[bool] = True,
- ):
- try:
- generation_result = orjson.loads(replies[0])
- reasoning = generation_result.get("reasoning", "")
- chart_type = generation_result.get("chart_type", "")
- if chart_schema := generation_result.get("chart_schema", {}):
- # sometimes the chart_schema is still in string format
- if isinstance(chart_schema, str):
- chart_schema = orjson.loads(chart_schema)
-
- chart_schema[
- "$schema"
- ] = "https://vega.github.io/schema/vega-lite/v5.json"
- chart_schema["data"] = {"values": sample_data}
-
- validate(chart_schema, schema=vega_schema)
-
- if remove_data_from_chart_schema:
- chart_schema["data"]["values"] = []
-
- return {
- "results": {
- "chart_schema": chart_schema,
- "reasoning": reasoning,
- "chart_type": chart_type,
- }
- }
-
- return {
- "results": {
- "chart_schema": {},
- "reasoning": reasoning,
- "chart_type": chart_type,
- }
- }
- except ValidationError as e:
- logger.exception(f"Vega-lite schema is not valid: {e}")
-
- return {
- "results": {
- "chart_schema": {},
- "reasoning": "",
- "chart_type": "",
- }
- }
- except Exception as e:
- logger.exception(f"JSON deserialization failed: {e}")
-
- return {
- "results": {
- "chart_schema": {},
- "reasoning": "",
- "chart_type": "",
- }
- }
-
-
-class ChartSchema(BaseModel):
- class ChartType(BaseModel):
- type: Literal["bar", "line", "area", "arc"]
-
- class ChartEncoding(BaseModel):
- field: str
- type: Literal["ordinal", "quantitative", "nominal"]
- title: str
-
- title: str
- mark: ChartType
- encoding: ChartEncoding
-
-
-class TemporalChartEncoding(ChartSchema.ChartEncoding):
- type: Literal["temporal"] = Field(default="temporal")
- timeUnit: str = Field(default="yearmonth")
-
-
-class LineChartSchema(ChartSchema):
- class LineChartMark(BaseModel):
- type: Literal["line"] = Field(default="line")
-
- class LineChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: ChartSchema.ChartEncoding
- color: ChartSchema.ChartEncoding
-
- mark: LineChartMark
- encoding: LineChartEncoding
-
-
-class MultiLineChartSchema(ChartSchema):
- class MultiLineChartMark(BaseModel):
- type: Literal["line"] = Field(default="line")
-
- class MultiLineChartTransform(BaseModel):
- fold: list[str]
- as_: list[str] = Field(alias="as")
-
- class MultiLineChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: ChartSchema.ChartEncoding
- color: ChartSchema.ChartEncoding
-
- mark: MultiLineChartMark
- transform: list[MultiLineChartTransform]
- encoding: MultiLineChartEncoding
-
-
-class BarChartSchema(ChartSchema):
- class BarChartMark(BaseModel):
- type: Literal["bar"] = Field(default="bar")
-
- class BarChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: ChartSchema.ChartEncoding
- color: ChartSchema.ChartEncoding
-
- mark: BarChartMark
- encoding: BarChartEncoding
-
-
-class GroupedBarChartSchema(ChartSchema):
- class GroupedBarChartMark(BaseModel):
- type: Literal["bar"] = Field(default="bar")
-
- class GroupedBarChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: ChartSchema.ChartEncoding
- xOffset: ChartSchema.ChartEncoding
- color: ChartSchema.ChartEncoding
-
- mark: GroupedBarChartMark
- encoding: GroupedBarChartEncoding
-
-
-class StackedBarChartYEncoding(ChartSchema.ChartEncoding):
- stack: Literal["zero"] = Field(default="zero")
-
-
-class StackedBarChartSchema(ChartSchema):
- class StackedBarChartMark(BaseModel):
- type: Literal["bar"] = Field(default="bar")
-
- class StackedBarChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: StackedBarChartYEncoding
- color: ChartSchema.ChartEncoding
-
- mark: StackedBarChartMark
- encoding: StackedBarChartEncoding
-
-
-class PieChartSchema(ChartSchema):
- class PieChartMark(BaseModel):
- type: Literal["arc"] = Field(default="arc")
-
- class PieChartEncoding(BaseModel):
- theta: ChartSchema.ChartEncoding
- color: ChartSchema.ChartEncoding
-
- mark: PieChartMark
- encoding: PieChartEncoding
-
-
-class AreaChartSchema(ChartSchema):
- class AreaChartMark(BaseModel):
- type: Literal["area"] = Field(default="area")
-
- class AreaChartEncoding(BaseModel):
- x: TemporalChartEncoding | ChartSchema.ChartEncoding
- y: ChartSchema.ChartEncoding
-
- mark: AreaChartMark
- encoding: AreaChartEncoding
-
-
-class ChartGenerationResults(BaseModel):
- reasoning: str
- chart_type: Literal[
- "line", "multi_line", "bar", "pie", "grouped_bar", "stacked_bar", "area", ""
- ] # empty string for no chart
- chart_schema: (
- LineChartSchema
- | MultiLineChartSchema
- | BarChartSchema
- | PieChartSchema
- | GroupedBarChartSchema
- | StackedBarChartSchema
- | AreaChartSchema
- )
diff --git a/wren-ai-service/src/pipelines/generation/utils/sql.py b/wren-ai-service/src/pipelines/generation/utils/sql.py
deleted file mode 100644
index 088282574..000000000
--- a/wren-ai-service/src/pipelines/generation/utils/sql.py
+++ /dev/null
@@ -1,573 +0,0 @@
-import logging
-from typing import Any, Dict, List
-
-import aiohttp
-import orjson
-from haystack import component
-from haystack.dataclasses import ChatMessage
-from pydantic import BaseModel
-
-from src.core.engine import (
- Engine,
- clean_generation_result,
-)
-from src.pipelines.retrieval.sql_knowledge import SqlKnowledge
-from src.web.v1.services.ask import AskHistory
-
-logger = logging.getLogger("wren-ai-service")
-
-
-@component
-class SQLGenPostProcessor:
- def __init__(self, engine: Engine):
- self._engine = engine
-
- @component.output_types(
- valid_generation_result=Dict[str, Any],
- invalid_generation_result=Dict[str, Any],
- )
- async def run(
- self,
- replies: List[str] | List[List[str]],
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- data_source: str = "",
- allow_data_preview: bool = False,
- ) -> dict:
- try:
- cleaned_generation_result = clean_generation_result(replies[0])
-
- # test if cleaned_generation_result in string format is actually a dictionary with key 'sql'
- if cleaned_generation_result.startswith("{"):
- cleaned_generation_result = orjson.loads(cleaned_generation_result)[
- "sql"
- ]
-
- (
- valid_generation_result,
- invalid_generation_result,
- ) = await self._classify_generation_result(
- cleaned_generation_result,
- project_id=project_id,
- use_dry_plan=use_dry_plan,
- allow_dry_plan_fallback=allow_dry_plan_fallback,
- data_source=data_source,
- allow_data_preview=allow_data_preview,
- )
-
- return {
- "valid_generation_result": valid_generation_result,
- "invalid_generation_result": invalid_generation_result,
- }
- except Exception as e:
- logger.exception(f"Error in SQLGenPostProcessor: {e}")
-
- return {
- "valid_generation_result": {},
- "invalid_generation_result": {},
- }
-
- async def _classify_generation_result(
- self,
- generation_result: str,
- project_id: str | None = None,
- use_dry_plan: bool = False,
- allow_dry_plan_fallback: bool = True,
- data_source: str = "",
- allow_data_preview: bool = False,
- ) -> Dict[str, str]:
- valid_generation_result = {}
- invalid_generation_result = {}
- use_dry_run = not allow_data_preview
-
- async with aiohttp.ClientSession() as session:
- if use_dry_plan:
- dry_plan_result, error_message = await self._engine.dry_plan(
- session,
- generation_result,
- data_source,
- allow_fallback=allow_dry_plan_fallback,
- )
-
- if dry_plan_result:
- valid_generation_result = {
- "sql": generation_result,
- "correlation_id": "",
- }
- else:
- invalid_generation_result = {
- "sql": generation_result,
- "type": "TIME_OUT"
- if error_message.startswith("Request timed out")
- else "DRY_PLAN",
- "error": error_message,
- "correlation_id": "",
- }
- elif use_dry_run:
- success, _, addition = await self._engine.execute_sql(
- generation_result,
- session,
- project_id=project_id,
- limit=1,
- dry_run=True,
- )
-
- if success:
- valid_generation_result = {
- "sql": generation_result,
- "correlation_id": addition.get("correlation_id", ""),
- }
- else:
- error_message = addition.get("error_message", "")
- invalid_generation_result = {
- "sql": addition.get("error_sql", generation_result),
- "original_sql": generation_result,
- "type": "TIME_OUT"
- if error_message.startswith("Request timed out")
- else "DRY_RUN",
- "error": error_message,
- "correlation_id": addition.get("correlation_id", ""),
- }
- else:
- has_data, _, addition = await self._engine.execute_sql(
- generation_result,
- session,
- project_id=project_id,
- limit=1,
- dry_run=False,
- )
-
- if has_data:
- valid_generation_result = {
- "sql": generation_result,
- "correlation_id": addition.get("correlation_id", ""),
- }
- else:
- error_message = addition.get("error_message", "")
- preview_data_status = (
- "PREVIEW_EMPTY_DATA"
- if error_message == ""
- else "PREVIEW_FAILED"
- )
- invalid_generation_result = {
- "sql": addition.get("error_sql", generation_result),
- "original_sql": generation_result,
- "type": "TIME_OUT"
- if error_message.startswith("Request timed out")
- else preview_data_status,
- "error": error_message,
- "correlation_id": addition.get("correlation_id", ""),
- }
-
- return valid_generation_result, invalid_generation_result
-
-
-_DEFAULT_TEXT_TO_SQL_RULES = """
-### SQL RULES ###
-- ONLY USE SELECT statements, NO DELETE, UPDATE OR INSERT etc. statements that might change the data in the database.
-- ONLY USE the tables and columns mentioned in the database schema.
-- ONLY USE "*" if the user query asks for all the columns of a table.
-- ONLY CHOOSE columns belong to the tables mentioned in the database schema.
-- DON'T INCLUDE comments in the generated SQL query.
-- YOU MUST USE "JOIN" if you choose columns from multiple tables!
-- PREFER USING CTEs over subqueries.
-- When generating SQL query, always:
- - Put double quotes around column and table names.
- - Put single quotes around string literals.
- - Never quote numeric literals.
- For example: SELECT "customers"."customer_name" FROM "customers" WHERE "customers"."city" = 'Taipei' and "customers"."year" = 1992;
-- YOU MUST USE "lower(.) like lower()" function or "lower(.) = lower()" function for case-insensitive comparison!
- - Use "lower(.) LIKE lower()" when:
- - The user requests a pattern or partial match.
- - The value is not specific enough to be a single, exact value.
- - Wildcards (%) are needed to capture the pattern.
- - Use "lower(.) = lower()" when:
- - The user requests an exact, specific value.
- - There is no ambiguity or pattern in the value.
-- If the column is date/time related field, and it is a INT/BIGINT/DOUBLE/FLOAT type, please use the appropriate function mentioned in the SQL FUNCTIONS section to cast the column to "TIMESTAMP" type first before using it in the query
- - example: TO_TIMESTAMP_MILLIS("") # if the timestamp_column is in milliseconds
- - example: TO_TIMESTAMP_SECONDS("") # if the timestamp_column is in seconds
- - example: TO_TIMESTAMP_MICROS("") # if the timestamp_column is in microseconds
-- ALWAYS CAST the date/time related field to "TIMESTAMP WITH TIME ZONE" type when using them in the query
- - example 1: CAST(properties_closedate AS TIMESTAMP WITH TIME ZONE)
- - example 2: CAST('2024-11-09 00:00:00' AS TIMESTAMP WITH TIME ZONE)
- - example 3: CAST(DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') AS TIMESTAMP WITH TIME ZONE)
-- If the user asks for a specific date, please give the date range in SQL query
- - example: "What is the total revenue for the month of 2024-11-01?"
- - answer: "SELECT SUM(r.PriceSum) FROM Revenue r WHERE CAST(r.PurchaseTimestamp AS TIMESTAMP WITH TIME ZONE) >= CAST('2024-11-01 00:00:00' AS TIMESTAMP WITH TIME ZONE) AND CAST(r.PurchaseTimestamp AS TIMESTAMP WITH TIME ZONE) < CAST('2024-11-02 00:00:00' AS TIMESTAMP WITH TIME ZONE)"
-- USE THE VIEW TO SIMPLIFY THE QUERY.
-- DON'T MISUSE THE VIEW NAME. THE ACTUAL NAME IS FOLLOWING THE CREATE VIEW STATEMENT.
-- ONLY USE table/column alias in the final SELECT clause; don't use table/columnalias in the other clauses.
-- Refer to the value of alias from the comment section of the corresponding table or column in the DATABASE SCHEMA section for reference when using alias in the final SELECT clause.
- - EXAMPLE
- DATABASE SCHEMA
- /* {"alias":"_orders","description":"A model representing the orders data."} */
- CREATE TABLE orders (
- -- {"description":"A column that represents the timestamp when the order was approved.","alias":"_timestamp"}
- ApprovedTimestamp TIMESTAMP
- }
-
- SQL
- SELECT "_orders"."ApprovedTimestamp" AS "_timestamp" FROM "orders" AS "_orders";
-- DON'T USE '.' in column/table alias, replace '.' with '_' in column/table alias.
-- DON'T USE "FILTER(WHERE )" clause in the generated SQL query.
-- DON'T USE "EXTRACT(EPOCH FROM )" clause in the generated SQL query.
-- DON'T USE "EXTRACT()" function with INTERVAL data types as arguments
-- DON'T USE INTERVAL or generate INTERVAL-like expression in the generated SQL query.
-- DON'T USE "TO_CHAR" function in the generated SQL query.
-- Aggregate functions are not allowed in the WHERE clause. Instead, they belong in the HAVING clause, which is used to filter after aggregation.
-- You can only add "ORDER BY" and "LIMIT" to the final "UNION" result.
-- For the ranking problem, you must use the ranking function, `DENSE_RANK()` to rank the results and then use `WHERE` clause to filter the results.
-- For the ranking problem, you must add the ranking column to the final SELECT clause.
-"""
-
-
-_DEFAULT_CALCULATED_FIELD_INSTRUCTIONS = """
-#### Instructions for Calculated Field ####
-
-The first structure is the special column marked as "Calculated Field". You need to interpret the purpose and calculation basis for these columns, then utilize them in the following text-to-sql generation tasks.
-First, provide a brief explanation of what each field represents in the context of the schema, including how each field is computed using the relationships between models.
-Then, during the following tasks, if the user queries pertain to any calculated fields defined in the database schema, ensure to utilize those calculated fields appropriately in the output SQL queries.
-The goal is to accurately reflect the intent of the question in the SQL syntax, leveraging the pre-computed logic embedded within the calculated fields.
-
-EXAMPLES:
-The given schema is created by the SQL command:
-
-CREATE TABLE orders (
- OrderId VARCHAR PRIMARY KEY,
- CustomerId VARCHAR,
- -- This column is a Calculated Field
- -- column expression: avg(reviews.Score)
- Rating DOUBLE,
- -- This column is a Calculated Field
- -- column expression: count(reviews.Id)
- ReviewCount BIGINT,
- -- This column is a Calculated Field
- -- column expression: count(order_items.ItemNumber)
- Size BIGINT,
- -- This column is a Calculated Field
- -- column expression: count(order_items.ItemNumber) > 1
- Large BOOLEAN,
- FOREIGN KEY (CustomerId) REFERENCES customers(Id)
-);
-
-Interpret the columns that are marked as Calculated Fields in the schema:
-Rating (DOUBLE) - Calculated as the average score (avg) of the Score field from the reviews table where the reviews are associated with the order. This field represents the overall customer satisfaction rating for the order based on review scores.
-ReviewCount (BIGINT) - Calculated by counting (count) the number of entries in the reviews table associated with this order. It measures the volume of customer feedback received for the order.
-Size (BIGINT) - Represents the total number of items in the order, calculated by counting the number of item entries (ItemNumber) in the order_items table linked to this order. This field is useful for understanding the scale or size of an order.
-Large (BOOLEAN) - A boolean value calculated to check if the number of items in the order exceeds one (count(order_items.ItemNumber) > 1). It indicates whether the order is considered large in terms of item quantity.
-
-And if the user input queries like these:
-1. "How many large orders have been placed by customer with ID 'C1234'?"
-2. "What is the average customer rating for orders that were rated by more than 10 reviewers?"
-
-For the first query:
-First try to intepret the user query, the user wants to know the average rating for orders which have attracted significant review activity, specifically those with more than 10 reviews.
-Then, according to the above intepretation about the given schema, the term 'Rating' is predefined in the Calculated Field of the 'orders' model. And, the number of reviews is also predefined in the 'ReviewCount' Calculated Field.
-So utilize those Calculated Fields in the SQL generation process to give an answer like this:
-
-SQL Query: SELECT AVG(Rating) FROM orders WHERE ReviewCount > 10
-"""
-
-_DEFAULT_METRIC_INSTRUCTIONS = """
-#### Instructions for Metric ####
-
-Second, you will learn how to effectively utilize the special "metric" structure in text-to-SQL generation tasks.
-Metrics in a data model simplify complex data analysis by structuring data through predefined dimensions and measures.
-This structuring closely mirrors the concept of OLAP (Online Analytical Processing) cubes but is implemented in a more flexible and SQL-friendly manner.
-
-The metric typically constructed of the following components:
-1. Base Object
-The "base object" of a metric indicates the primary data source or table that provides the raw data.
-Metrics are constructed by selecting specific data points (dimensions and measures) from this base object, effectively creating a summarized or aggregated view of the data that can be queried like a normal table.
-Base object is the attribute of the metric, showing the origin of this metric and is typically not used in the query.
-2. Dimensions
-Dimensions in a metric represent the various axes along which data can be segmented for analysis.
-These are fields that provide a categorical breakdown of data.
-Each dimension provides a unique perspective on the data, allowing users to "slice and dice" the data cube to view different facets of the information contained within the base dataset.
-Dimensions are used as table columns in the querying process. Querying a dimension means to get the statistic from the certain perspective.
-3. Measures
-Measures are numerical or quantitative statistics calculated from the data. Measures are key results or outputs derived from data aggregation functions like SUM, COUNT, or AVG.
-Measures are used as table columns in the querying process, and are the main querying items in the metric structure.
-The expression of a measure represents the definition of the that users are intrested in. Make sure to understand the meaning of measures from their expressions.
-4. Time Grain
-Time Grain specifies the granularity of time-based data aggregation, such as daily, monthly, or yearly, facilitating trend analysis over specified periods.
-
-If the given schema contains the structures marked as 'metric', you should first interpret the metric schema based on the above definition.
-Then, during the following tasks, if the user queries pertain to any metrics defined in the database schema, ensure to utilize those metrics appropriately in the output SQL queries.
-The target is making complex data analysis more accessible and manageable by pre-aggregating data and structuring it using the metric structure, and supporting direct querying for business insights.
-
-EXAMPLES:
-The given schema is created by the SQL command:
-
-/* This table is a metric */
-/* Metric Base Object: orders */
-CREATE TABLE Revenue (
- -- This column is a dimension
- PurchaseTimestamp TIMESTAMP,
- -- This column is a dimension
- CustomerId VARCHAR,
- -- This column is a dimension
- Status VARCHAR,
- -- This column is a measure
- -- expression: sum(order_items.Price)
- PriceSum DOUBLE,
- -- This column is a measure
- -- expression: count(OrderId)
- NumberOfOrders BIGINT
-);
-
-Interpret the metric with the understanding of the metric structure:
-1. Base Object: orders
-This is the primary data source for the metric.
-The orders table provides the underlying data from which dimensions and measures are derived.
-It is the foundation upon which the metric is built, though it itself is not directly used in queries against the Revenue table.
-It shows the reference between the 'Revenue' metric and the 'orders' model. For the user queries pretain to the 'Revenue' of 'orders', the metric should be utilize in the sql generation process.
-2. Dimensions
-The metric contains the columns marked as 'dimension'. They can be interpreted as below:
-- PurchaseTimestamp (TIMESTAMP)
- Acts as a temporal dimension, allowing analysis of revenue over time. This can be used to observe trends, seasonal variations, or performance over specific periods.
-- CustomerId (VARCHAR)
- A key dimension for customer segmentation, it enables the analysis of revenue generated from individual customers or customer groups.
-- Status (VARCHAR)
- Reflects the current state of an order (e.g., pending, completed, cancelled). This dimension is crucial for analyses that differentiate performance based on order status.
-3. Measures
-The metric contains the columns marked as 'measure'. They can be interpreted as below:
-- PriceSum (DOUBLE)
- A financial measure calculated as sum(order_items.Price), representing the total revenue generated from orders. This measure is vital for tracking overall sales performance and is the primary output of interest in many financial and business analyses.
-- NumberOfOrders (BIGINT)
- A count measure that provides the total number of orders. This is essential for operational metrics, such as assessing the volume of business activity and evaluating the efficiency of sales processes.
-
-Now, if the user input queries like this:
-Question: "What was the total revenue from each customer last month?"
-
-First try to intepret the user query, the user asks for a breakdown of the total revenue generated by each customer in the previous calendar month.
-The user is specifically interested in understanding how much each customer contributed to the total sales during this period.
-To answer this question, it is suitable to use the following components from the metric:
-1. CustomerId (Dimension): This will be used to group the revenue data by each unique customer, allowing us to segment the total revenue by customer.
-2. PurchaseTimestamp (Dimension): This timestamp field will be used to filter the data to only include orders from the last month.
-3. PriceSum (Measure): Since PriceSum is a pre-aggregated measure of total revenue (sum of order_items.Price), it can be directly used to sum up the revenue without needing further aggregation in the SQL query.
-So utilize those metric components in the SQL generation process to give an answer like this:
-
-SQL Query:
-SELECT
- CustomerId,
- PriceSum AS TotalRevenue
-FROM
- Revenue
-WHERE
- PurchaseTimestamp >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL '1 month') AND
- PurchaseTimestamp < DATE_TRUNC('month', CURRENT_DATE)
-"""
-
-_DEFAULT_JSON_FIELD_INSTRUCTIONS = """
-#### Instructions for JSON related functions ####
-- ONLY USE JSON_QUERY for querying fields if "json_type":"JSON" is identified in the columns comment, NOT the deprecated JSON_EXTRACT_SCALAR function.
- - DON'T USE CAST for JSON fields, ONLY USE the following funtions:
- - LAX_BOOL for boolean fields
- - LAX_FLOAT64 for double and float fields
- - LAX_INT64 for bigint fields
- - LAX_STRING for varchar fields
- - For Example:
- DATA SCHEMA:
- `/* {"alias":"users","description":"A model representing the users data."} */
- CREATE TABLE users (
- -- {"alias":"address","description":"A JSON object that represents address information of this user.","json_type":"JSON","json_fields":{"json_type":"JSON","address.json.city":{"name":"city","type":"varchar","path":"$.city","properties":{"alias":"city","description":"City Name."}},"address.json.state":{"name":"state","type":"varchar","path":"$.state","properties":{"alias":"state","description":"ISO code or name of the state, province or district."}},"address.json.postcode":{"name":"postcode","type":"varchar","path":"$.postcode","properties":{"alias":"postcode","description":"Postal code."}},"address.json.country":{"name":"country","type":"varchar","path":"$.country","properties":{"alias":"country","description":"ISO code of the country."}}}}
- address JSON
- )`
- To get the city of address in user table use SQL:
- `SELECT LAX_STRING(JSON_QUERY(u.address, '$.city')) FROM user as u`
-- ONLY USE JSON_QUERY_ARRAY for querying "json_type":"JSON_ARRAY" is identified in the comment of the column, NOT the deprecated JSON_EXTRACT_ARRAY.
- - USE UNNEST to analysis each item individually in the ARRAY. YOU MUST SELECT FROM the parent table ahead of the UNNEST ARRAY.
- - The alias of the UNNEST(ARRAY) should be in the format `unnest_table_alias(individual_item_alias)`
- - For Example: `SELECT item FROM UNNEST(ARRAY[1,2,3]) as my_unnested_table(item)`
- - If the items in the ARRAY are JSON objects, use JSON_QUERY to query the fields inside each JSON item.
- - For Example:
- DATA SCHEMA
- `/* {"alias":"my_table","description":"A test my_table"} */
- CREATE TABLE my_table (
- -- {"alias":"elements","description":"elements column","json_type":"JSON_ARRAY","json_fields":{"json_type":"JSON_ARRAY","elements.json_array.id":{"name":"id","type":"bigint","path":"$.id","properties":{"alias":"id","description":"data ID."}},"elements.json_array.key":{"name":"key","type":"varchar","path":"$.key","properties":{"alias":"key","description":"data Key."}},"elements.json_array.value":{"name":"value","type":"varchar","path":"$.value","properties":{"alias":"value","description":"data Value."}}}}
- elements JSON
- )`
- To get the number of elements in my_table table use SQL:
- `SELECT LAX_INT64(JSON_QUERY(element, '$.number')) FROM my_table as t, UNNEST(JSON_QUERY_ARRAY(elements)) AS my_unnested_table(element) WHERE LAX_FLOAT64(JSON_QUERY(element, '$.value')) > 3.5`
- - To JOIN ON the fields inside UNNEST(ARRAY), YOU MUST SELECT FROM the parent table ahead of the UNNEST syntax, and the alias of the UNNEST(ARRAY) SHOULD BE IN THE FORMAT unnest_table_alias(individual_item_alias)
- - For Example: `SELECT p.column_1, j.column_2 FROM parent_table AS p, join_table AS j JOIN UNNEST(p.array_column) AS unnested(array_item) ON j.id = array_item.id`
-- DON'T USE JSON_QUERY and JSON_QUERY_ARRAY when "json_type":"".
-- DON'T USE LAX_BOOL, LAX_FLOAT64, LAX_INT64, LAX_STRING when "json_type":"".
-"""
-
-sql_samples_instructions = """
-#### Instructions for SQL Samples ####
-
-Finally, you will learn from the sample SQL queries provided in the input. These samples demonstrate best practices and common patterns for querying this specific database.
-
-For each sample, you should:
-1. Study the question that explains what the query aims to accomplish
-2. Analyze the SQL implementation to understand:
- - Table structures and relationships used
- - Specific functions and operators employed
- - Query patterns and techniques demonstrated
-3. Use these samples as reference patterns when generating similar queries
-4. Adapt the techniques shown in the samples to match new query requirements while maintaining consistent style and approach
-
-The samples will help you understand:
-- Preferred table join patterns
-- Common aggregation methods
-- Specific function usage
-- Query structure and formatting conventions
-
-When generating new queries, try to follow similar patterns when applicable, while adapting them to the specific requirements of each new query.
-
-Learn about the usage of the schema structures and generate SQL based on them.
-"""
-
-
-sql_generation_reasoning_system_prompt = """
-### TASK ###
-You are a helpful data analyst who is great at thinking deeply and reasoning about the user's question and the database schema, and you provide a step-by-step reasoning plan in order to answer the user's question.
-
-### INSTRUCTIONS ###
-1. Think deeply and reason about the user's question, the database schema, and the user's query history if provided.
-2. Explicitly state the following information in the reasoning plan:
-if the user puts any specific timeframe(e.g. YYYY-MM-DD) in the user's question(excluding the value of the current time), you will put the absolute time frame in the SQL query;
-otherwise, you will put the relative timeframe in the SQL query.
-3. For the ranking problem(e.g. "top x", "bottom x", "first x", "last x"), you must use the ranking function, `DENSE_RANK()` to rank the results and then use `WHERE` clause to filter the results.
-4. For the ranking problem(e.g. "top x", "bottom x", "first x", "last x"), you must add the ranking column to the final SELECT clause.
-5. If USER INSTRUCTIONS section is provided, make sure to consider them in the reasoning plan.
-6. If SQL SAMPLES section is provided, make sure to consider them in the reasoning plan.
-7. Give a step by step reasoning plan in order to answer user's question.
-8. The reasoning plan should be in the language same as the language user provided in the input.
-9. Don't include SQL in the reasoning plan.
-10. Each step in the reasoning plan must start with a number, a title(in bold format in markdown), and a reasoning for the step.
-11. Do not include ```markdown or ``` in the answer.
-12. A table name in the reasoning plan must be in this format: `table: `.
-13. A column name in the reasoning plan must be in this format: `column: .`.
-14. ONLY SHOWING the reasoning plan in bullet points.
-
-### FINAL ANSWER FORMAT ###
-The final answer must be a reasoning plan in plain Markdown string format
-"""
-
-
-def _extract_from_sql_knowledge(
- sql_knowledge: SqlKnowledge | None, attribute_name: str, default_value: str
-) -> str:
- if sql_knowledge is None:
- return default_value
-
- value = getattr(sql_knowledge, attribute_name, "")
- return value if value and value.strip() else default_value
-
-
-def get_text_to_sql_rules(sql_knowledge: SqlKnowledge | None = None) -> str:
- if sql_knowledge is not None:
- return _extract_from_sql_knowledge(
- sql_knowledge, "text_to_sql_rule", _DEFAULT_TEXT_TO_SQL_RULES
- )
-
- return _DEFAULT_TEXT_TO_SQL_RULES
-
-
-def get_calculated_field_instructions(sql_knowledge: SqlKnowledge | None = None) -> str:
- if sql_knowledge is not None:
- return _extract_from_sql_knowledge(
- sql_knowledge,
- "calculated_field_instructions",
- _DEFAULT_CALCULATED_FIELD_INSTRUCTIONS,
- )
-
- return _DEFAULT_CALCULATED_FIELD_INSTRUCTIONS
-
-
-def get_metric_instructions(sql_knowledge: SqlKnowledge | None = None) -> str:
- if sql_knowledge is not None:
- return _extract_from_sql_knowledge(
- sql_knowledge, "metric_instructions", _DEFAULT_METRIC_INSTRUCTIONS
- )
-
- return _DEFAULT_METRIC_INSTRUCTIONS
-
-
-def get_json_field_instructions(sql_knowledge: SqlKnowledge | None = None) -> str:
- if sql_knowledge is not None:
- return _extract_from_sql_knowledge(
- sql_knowledge, "json_field_instructions", _DEFAULT_JSON_FIELD_INSTRUCTIONS
- )
-
- return _DEFAULT_JSON_FIELD_INSTRUCTIONS
-
-
-def get_sql_generation_system_prompt(sql_knowledge: SqlKnowledge | None = None) -> str:
- text_to_sql_rules = get_text_to_sql_rules(sql_knowledge)
-
- return f"""
-You are a helpful assistant that converts natural language queries into ANSI SQL queries.
-
-Given user's question, database schema, etc., you should think deeply and carefully and generate the SQL query based on the given reasoning plan step by step.
-
-### GENERAL RULES ###
-
-1. YOU MUST FOLLOW the instructions strictly to generate the SQL query if the section of USER INSTRUCTIONS is available in user's input.
-2. YOU MUST ONLY CHOOSE the appropriate functions from the sql functions list and use them in the SQL query if the section of SQL FUNCTIONS is available in user's input.
-3. YOU MUST REFER to the sql samples and learn the usage of the schema structures and how SQL is written based on them if the section of SQL SAMPLES is available in user's input.
-4. YOU MUST FOLLOW the reasoning plan step by step strictly to generate the SQL query if the section of REASONING PLAN is available in user's input.
-5. YOU MUST FOLLOW SQL Rules if they are not contradicted with instructions.
-
-{text_to_sql_rules}
-
-### FINAL ANSWER FORMAT ###
-The final answer must be a ANSI SQL query in JSON format:
-
-{{
- "sql":
-}}
-"""
-
-
-class SqlGenerationResult(BaseModel):
- sql: str
-
-
-SQL_GENERATION_MODEL_KWARGS = {
- "response_format": {
- "type": "json_schema",
- "json_schema": {
- "name": "sql_generation_result",
- "schema": SqlGenerationResult.model_json_schema(),
- },
- }
-}
-
-
-def construct_instructions(
- instructions: list[dict] | None = None,
-):
- _instructions = []
- if instructions:
- _instructions += [
- instruction.get("instruction") for instruction in instructions
- ]
-
- return _instructions
-
-
-def construct_ask_history_messages(
- histories: list[AskHistory] | list[dict],
-) -> list[ChatMessage]:
- messages = []
- for history in histories:
- messages.append(
- ChatMessage.from_user(
- history.question
- if hasattr(history, "question")
- else history["question"]
- )
- )
- messages.append(
- ChatMessage.from_assistant(
- history.sql if hasattr(history, "sql") else history["sql"]
- )
- )
- return messages
diff --git a/wren-ai-service/src/pipelines/generation/utils/vega-lite-schema-v5.json b/wren-ai-service/src/pipelines/generation/utils/vega-lite-schema-v5.json
deleted file mode 100644
index 83fe66bda..000000000
--- a/wren-ai-service/src/pipelines/generation/utils/vega-lite-schema-v5.json
+++ /dev/null
@@ -1,32516 +0,0 @@
-{
- "$ref": "#/definitions/TopLevelSpec",
- "$schema": "http://json-schema.org/draft-07/schema#",
- "definitions": {
- "Aggregate": {
- "anyOf": [
- {
- "$ref": "#/definitions/NonArgAggregateOp"
- },
- {
- "$ref": "#/definitions/ArgmaxDef"
- },
- {
- "$ref": "#/definitions/ArgminDef"
- }
- ]
- },
- "AggregateOp": {
- "enum": [
- "argmax",
- "argmin",
- "average",
- "count",
- "distinct",
- "max",
- "mean",
- "median",
- "min",
- "missing",
- "product",
- "q1",
- "q3",
- "ci0",
- "ci1",
- "stderr",
- "stdev",
- "stdevp",
- "sum",
- "valid",
- "values",
- "variance",
- "variancep",
- "exponential",
- "exponentialb"
- ],
- "type": "string"
- },
- "AggregateTransform": {
- "additionalProperties": false,
- "properties": {
- "aggregate": {
- "description": "Array of objects that define fields to aggregate.",
- "items": {
- "$ref": "#/definitions/AggregatedFieldDef"
- },
- "type": "array"
- },
- "groupby": {
- "description": "The data fields to group by. If not specified, a single group containing all data objects will be used.",
- "items": {
- "$ref": "#/definitions/FieldName"
- },
- "type": "array"
- }
- },
- "required": [
- "aggregate"
- ],
- "type": "object"
- },
- "AggregatedFieldDef": {
- "additionalProperties": false,
- "properties": {
- "as": {
- "$ref": "#/definitions/FieldName",
- "description": "The output field names to use for each aggregated field."
- },
- "field": {
- "$ref": "#/definitions/FieldName",
- "description": "The data field for which to compute aggregate function. This is required for all aggregation operations except `\"count\"`."
- },
- "op": {
- "$ref": "#/definitions/AggregateOp",
- "description": "The aggregation operation to apply to the fields (e.g., `\"sum\"`, `\"average\"`, or `\"count\"`). See the [full list of supported aggregation operations](https://vega.github.io/vega-lite/docs/aggregate.html#ops) for more information."
- }
- },
- "required": [
- "op",
- "as"
- ],
- "type": "object"
- },
- "Align": {
- "enum": [
- "left",
- "center",
- "right"
- ],
- "type": "string"
- },
- "AllSortString": {
- "anyOf": [
- {
- "$ref": "#/definitions/SortOrder"
- },
- {
- "$ref": "#/definitions/SortByChannel"
- },
- {
- "$ref": "#/definitions/SortByChannelDesc"
- }
- ]
- },
- "AnyMark": {
- "anyOf": [
- {
- "$ref": "#/definitions/CompositeMark"
- },
- {
- "$ref": "#/definitions/CompositeMarkDef"
- },
- {
- "$ref": "#/definitions/Mark"
- },
- {
- "$ref": "#/definitions/MarkDef"
- }
- ]
- },
- "AnyMarkConfig": {
- "anyOf": [
- {
- "$ref": "#/definitions/MarkConfig"
- },
- {
- "$ref": "#/definitions/AreaConfig"
- },
- {
- "$ref": "#/definitions/BarConfig"
- },
- {
- "$ref": "#/definitions/RectConfig"
- },
- {
- "$ref": "#/definitions/LineConfig"
- },
- {
- "$ref": "#/definitions/TickConfig"
- }
- ]
- },
- "AreaConfig": {
- "additionalProperties": false,
- "properties": {
- "align": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). One of `\"left\"`, `\"right\"`, `\"center\"`.\n\n__Note:__ Expression reference is *not* supported for range marks."
- },
- "angle": {
- "anyOf": [
- {
- "description": "The rotation angle of the text, in degrees.",
- "maximum": 360,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "aria": {
- "anyOf": [
- {
- "description": "A boolean flag indicating if [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) should be included (SVG output only). If `false`, the \"aria-hidden\" attribute will be set on the output SVG element, removing the mark item from the ARIA accessibility tree.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ariaRole": {
- "anyOf": [
- {
- "description": "Sets the type of user interface element of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the \"role\" attribute. Warning: this property is experimental and may be changed in the future.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ariaRoleDescription": {
- "anyOf": [
- {
- "description": "A human-readable, author-localized description for the role of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the \"aria-roledescription\" attribute. Warning: this property is experimental and may be changed in the future.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "aspect": {
- "anyOf": [
- {
- "description": "Whether to keep aspect ratio of image marks.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "baseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "For text marks, the vertical text baseline. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, `\"line-bottom\"`, or an expression reference that provides one of the valid values. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the `lineHeight` rather than `fontSize` alone.\n\nFor range marks, the vertical alignment of the marks. One of `\"top\"`, `\"middle\"`, `\"bottom\"`.\n\n__Note:__ Expression reference is *not* supported for range marks."
- },
- "blend": {
- "anyOf": [
- {
- "$ref": "#/definitions/Blend",
- "description": "The color blend mode for drawing an item on its current background. Any valid [CSS mix-blend-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) value can be used.\n\n__Default value: `\"source-over\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "color": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default color.\n\n__Default value:__ ■ `\"#4682b4\"`\n\n__Note:__\n- This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n- The `fill` and `stroke` properties have higher precedence than `color` and will override `color`."
- },
- "cornerRadius": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles or arcs' corners.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusBottomLeft": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' bottom left corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusBottomRight": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' bottom right corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusTopLeft": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' top right corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusTopRight": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' top left corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cursor": {
- "anyOf": [
- {
- "$ref": "#/definitions/Cursor",
- "description": "The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "description": {
- "anyOf": [
- {
- "description": "A text description of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the [\"aria-label\" attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dir": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextDirection",
- "description": "The direction of the text. One of `\"ltr\"` (left-to-right) or `\"rtl\"` (right-to-left). This property determines on which side is truncated in response to the limit parameter.\n\n__Default value:__ `\"ltr\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dx": {
- "anyOf": [
- {
- "description": "The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dy": {
- "anyOf": [
- {
- "description": "The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ellipsis": {
- "anyOf": [
- {
- "description": "The ellipsis string for text truncated in response to the limit parameter.\n\n__Default value:__ `\"…\"`",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "endAngle": {
- "anyOf": [
- {
- "description": "The end angle in radians for arc marks. A value of `0` indicates up (north), increasing values proceed clockwise.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fill": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default fill color. This property has higher precedence than `config.color`. Set to `null` to remove fill.\n\n__Default value:__ (None)"
- },
- "fillOpacity": {
- "anyOf": [
- {
- "description": "The fill opacity (value between [0,1]).\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "filled": {
- "description": "Whether the mark's color should be used as fill color instead of stroke color.\n\n__Default value:__ `false` for all `point`, `line`, and `rule` marks as well as `geoshape` marks for [`graticule`](https://vega.github.io/vega-lite/docs/data.html#graticule) data sources; otherwise, `true`.\n\n__Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).",
- "type": "boolean"
- },
- "font": {
- "anyOf": [
- {
- "description": "The typeface to set the text in (e.g., `\"Helvetica Neue\"`).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontSize": {
- "anyOf": [
- {
- "description": "The font size, in pixels.\n\n__Default value:__ `11`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "The font style (e.g., `\"italic\"`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "The font weight. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "height": {
- "anyOf": [
- {
- "description": "Height of the marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "href": {
- "anyOf": [
- {
- "$ref": "#/definitions/URI",
- "description": "A URL to load upon mouse click. If defined, the mark acts as a hyperlink."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "innerRadius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The inner radius in pixels of arc marks. `innerRadius` is an alias for `radius2`.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "interpolate": {
- "anyOf": [
- {
- "$ref": "#/definitions/Interpolate",
- "description": "The line interpolation method to use for line and area marks. One of the following:\n- `\"linear\"`: piecewise linear segments, as in a polyline.\n- `\"linear-closed\"`: close the linear segments to form a polygon.\n- `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n- `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n- `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n- `\"basis\"`: a B-spline, with control point duplication on the ends.\n- `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n- `\"basis-closed\"`: a closed B-spline, as in a loop.\n- `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n- `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n- `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n- `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n- `\"monotone\"`: cubic interpolation that preserves monotonicity in y."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "invalid": {
- "anyOf": [
- {
- "$ref": "#/definitions/MarkInvalidDataMode"
- },
- {
- "type": "null"
- }
- ],
- "description": "Invalid data mode, which defines how the marks and corresponding scales should represent invalid values (`null` and `NaN` in continuous scales *without* defined output for invalid values).\n\n- `\"filter\"` — *Exclude* all invalid values from the visualization's *marks* and *scales*. For path marks (for line, area, trail), this option will create paths that connect valid points, as if the data rows with invalid values do not exist.\n\n- `\"break-paths-filter-domains\"` — Break path marks (for line, area, trail) at invalid values. For non-path marks, this is equivalent to `\"filter\"`. All *scale* domains will *exclude* these filtered data points.\n\n- `\"break-paths-show-domains\"` — Break paths (for line, area, trail) at invalid values. Hide invalid values for non-path marks. All *scale* domains will *include* these filtered data points (for both path and non-path marks).\n\n- `\"show\"` or `null` — Show all data points in the marks and scale domains. Each scale will use the output for invalid values defined in `config.scale.invalid` or, if unspecified, by default invalid values will produce the same visual values as zero (if the scale includes zero) or the minimum value (if the scale does not include zero).\n\n- `\"break-paths-show-path-domains\"` (default) — This is equivalent to `\"break-paths-show-domains\"` for path-based marks (line/area/trail) and `\"filter\"` for non-path marks.\n\n__Note__: If any channel's scale has an output for invalid values defined in `config.scale.invalid`, all values for the scales will be considered \"valid\" since they can produce a reasonable output for the scales. Thus, fields for such channels will not be filtered and will not cause path breaks."
- },
- "limit": {
- "anyOf": [
- {
- "description": "The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n\n__Default value:__ `0` -- indicating no limit",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "line": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/OverlayMarkDef"
- }
- ],
- "description": "A flag for overlaying line on top of area marks, or an object defining the properties of the overlayed lines.\n\n- If this value is an empty object (`{}`) or `true`, lines with default properties will be used.\n\n- If this value is `false`, no lines would be automatically added to area marks.\n\n__Default value:__ `false`."
- },
- "lineBreak": {
- "anyOf": [
- {
- "description": "A delimiter, such as a newline character, upon which to break text strings into multiple lines. This property is ignored if the text is array-valued.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "lineHeight": {
- "anyOf": [
- {
- "description": "The line height in pixels (the spacing between subsequent lines of text) for multi-line text marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "opacity": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The overall opacity (value between [0,1]).\n\n__Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise.",
- "maximum": 1,
- "minimum": 0
- },
- "order": {
- "description": "For line and trail marks, this `order` property can be set to `null` or `false` to make the lines use the original order in the data sources.",
- "type": [
- "null",
- "boolean"
- ]
- },
- "orient": {
- "$ref": "#/definitions/Orientation",
- "description": "The orientation of a non-stacked bar, tick, area, and line charts. The value is either horizontal (default) or vertical.\n- For bar, rule and tick, this determines whether the size of the bar and tick should be applied to x or y dimension.\n- For area, this property determines the orient property of the Vega output.\n- For line and trail marks, this property determines the sort order of the points in the line if `config.sortLineBy` is not specified. For stacked charts, this is always determined by the orientation of the stack; therefore explicitly specified value will be ignored."
- },
- "outerRadius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The outer radius in pixels of arc marks. `outerRadius` is an alias for `radius`.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "padAngle": {
- "anyOf": [
- {
- "description": "The angular padding applied to sides of the arc, in radians.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "point": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/OverlayMarkDef"
- },
- {
- "const": "transparent",
- "type": "string"
- }
- ],
- "description": "A flag for overlaying points on top of line or area marks, or an object defining the properties of the overlayed points.\n\n- If this property is `\"transparent\"`, transparent points will be used (for enhancing tooltips and selections).\n\n- If this property is an empty object (`{}`) or `true`, filled points with default properties will be used.\n\n- If this property is `false`, no points would be automatically added to line or area marks.\n\n__Default value:__ `false`."
- },
- "radius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "For arc mark, the primary (outer) radius in pixels.\n\nFor text marks, polar coordinate radial offset, in pixels, of the text from the origin determined by the `x` and `y` properties.\n\n__Default value:__ `min(plot_width, plot_height)/2`",
- "minimum": 0
- },
- "radius2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The secondary (inner) radius in pixels of arc marks.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "shape": {
- "anyOf": [
- {
- "anyOf": [
- {
- "$ref": "#/definitions/SymbolShape"
- },
- {
- "type": "string"
- }
- ],
- "description": "Shape of the point marks. Supported values include:\n- plotting shapes: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, `\"triangle-down\"`, `\"triangle-right\"`, or `\"triangle-left\"`.\n- the line symbol `\"stroke\"`\n- centered directional shapes `\"arrow\"`, `\"wedge\"`, or `\"triangle\"`\n- a custom [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.)\n\n__Default value:__ `\"circle\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "size": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default size for marks.\n- For `point`/`circle`/`square`, this represents the pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value.\n- For `bar`, this represents the band size of the bar, in pixels.\n- For `text`, this represents the font size, in pixels.\n\n__Default value:__\n- `30` for point, circle, square marks; width/height's `step`\n- `2` for bar marks with discrete dimensions;\n- `5` for bar marks with continuous dimensions;\n- `11` for text marks.",
- "minimum": 0
- },
- "smooth": {
- "anyOf": [
- {
- "description": "A boolean flag (default true) indicating if the image should be smoothed when resized. If false, individual pixels should be scaled directly rather than interpolated with smoothing. For SVG rendering, this option may not work in some browsers due to lack of standardization.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "startAngle": {
- "anyOf": [
- {
- "description": "The start angle in radians for arc marks. A value of `0` indicates up (north), increasing values proceed clockwise.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "stroke": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default stroke color. This property has higher precedence than `config.color`. Set to `null` to remove stroke.\n\n__Default value:__ (None)"
- },
- "strokeCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for line ending style. One of `\"butt\"`, `\"round\"`, or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeDash": {
- "anyOf": [
- {
- "description": "An array of alternating stroke, space lengths for creating dashed or dotted lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeDashOffset": {
- "anyOf": [
- {
- "description": "The offset (in pixels) into which to begin drawing with the stroke dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeJoin": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeJoin",
- "description": "The stroke line join method. One of `\"miter\"`, `\"round\"` or `\"bevel\"`.\n\n__Default value:__ `\"miter\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeMiterLimit": {
- "anyOf": [
- {
- "description": "The miter limit at which to bevel a line join.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeOffset": {
- "anyOf": [
- {
- "description": "The offset in pixels at which to draw the group stroke and fill. If unspecified, the default behavior is to dynamically offset stroked groups such that 1 pixel stroke widths align with the pixel grid.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeOpacity": {
- "anyOf": [
- {
- "description": "The stroke opacity (value between [0,1]).\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeWidth": {
- "anyOf": [
- {
- "description": "The stroke width, in pixels.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tension": {
- "anyOf": [
- {
- "description": "Depending on the interpolation type, sets the tension parameter (for line and area marks).",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "text": {
- "anyOf": [
- {
- "$ref": "#/definitions/Text",
- "description": "Placeholder text if the `text` channel is not specified"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "theta": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "- For arc marks, the arc length in radians if theta2 is not specified, otherwise the start arc angle. (A value of 0 indicates up or “north”, increasing values proceed clockwise.)\n\n- For text marks, polar coordinate angle in radians.",
- "maximum": 360,
- "minimum": 0
- },
- "theta2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The end angle of arc marks in radians. A value of 0 indicates up or “north”, increasing values proceed clockwise."
- },
- "time": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "timeUnitBandPosition": {
- "description": "Default relative band position for a time unit. If set to `0`, the marks will be positioned at the beginning of the time unit band step. If set to `0.5`, the marks will be positioned in the middle of the time unit band step.",
- "type": "number"
- },
- "timeUnitBandSize": {
- "description": "Default relative band size for a time unit. If set to `1`, the bandwidth of the marks will be equal to the time unit band step. If set to `0.5`, bandwidth of the marks will be half of the time unit band step.",
- "type": "number"
- },
- "tooltip": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "type": "string"
- },
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/TooltipContent"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "type": "null"
- }
- ],
- "description": "The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from.\n\n- If `tooltip` is `true` or `{\"content\": \"encoding\"}`, then all fields from `encoding` will be used.\n- If `tooltip` is `{\"content\": \"data\"}`, then all fields that appear in the highlighted data point will be used.\n- If set to `null` or `false`, then no tooltip will be used.\n\nSee the [`tooltip`](https://vega.github.io/vega-lite/docs/tooltip.html) documentation for a detailed discussion about tooltip in Vega-Lite.\n\n__Default value:__ `null`"
- },
- "url": {
- "anyOf": [
- {
- "$ref": "#/definitions/URI",
- "description": "The URL of the image file for image marks."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "width": {
- "anyOf": [
- {
- "description": "Width of the marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "x": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "width",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"` without specified `x2` or `width`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "x2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "width",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "y": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "height",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"` without specified `y2` or `height`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- },
- "y2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "height",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- }
- },
- "type": "object"
- },
- "ArgmaxDef": {
- "additionalProperties": false,
- "properties": {
- "argmax": {
- "$ref": "#/definitions/FieldName"
- }
- },
- "required": [
- "argmax"
- ],
- "type": "object"
- },
- "ArgminDef": {
- "additionalProperties": false,
- "properties": {
- "argmin": {
- "$ref": "#/definitions/FieldName"
- }
- },
- "required": [
- "argmin"
- ],
- "type": "object"
- },
- "AutoSizeParams": {
- "additionalProperties": false,
- "properties": {
- "contains": {
- "description": "Determines how size calculation should be performed, one of `\"content\"` or `\"padding\"`. The default setting (`\"content\"`) interprets the width and height settings as the data rectangle (plotting) dimensions, to which padding is then added. In contrast, the `\"padding\"` setting includes the padding within the view size calculations, such that the width and height settings indicate the **total** intended size of the view.\n\n__Default value__: `\"content\"`",
- "enum": [
- "content",
- "padding"
- ],
- "type": "string"
- },
- "resize": {
- "description": "A boolean flag indicating if autosize layout should be re-calculated on every view update.\n\n__Default value__: `false`",
- "type": "boolean"
- },
- "type": {
- "$ref": "#/definitions/AutosizeType",
- "description": "The sizing format type. One of `\"pad\"`, `\"fit\"`, `\"fit-x\"`, `\"fit-y\"`, or `\"none\"`. See the [autosize type](https://vega.github.io/vega-lite/docs/size.html#autosize) documentation for descriptions of each.\n\n__Default value__: `\"pad\"`"
- }
- },
- "type": "object"
- },
- "AutosizeType": {
- "enum": [
- "pad",
- "none",
- "fit",
- "fit-x",
- "fit-y"
- ],
- "type": "string"
- },
- "Axis": {
- "additionalProperties": false,
- "properties": {
- "aria": {
- "anyOf": [
- {
- "description": "A boolean flag indicating if [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) should be included (SVG output only). If `false`, the \"aria-hidden\" attribute will be set on the output SVG group, removing the axis from the ARIA accessibility tree.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "bandPosition": {
- "anyOf": [
- {
- "description": "An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands.\n\n __Default value:__ `0.5`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "description": {
- "anyOf": [
- {
- "description": "A text description of this axis for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If the `aria` property is true, for SVG output the [\"aria-label\" attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) will be set to this description. If the description is unspecified it will be automatically generated.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domain": {
- "description": "A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "domainCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for the domain line's ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of axis domain line.\n\n__Default value:__ `\"gray\"`."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed domain lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the domain dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the axis domain line.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainWidth": {
- "anyOf": [
- {
- "description": "Stroke width of axis domain line\n\n__Default value:__ `1`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "format": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "$ref": "#/definitions/Dict"
- }
- ],
- "description": "When used with the default `\"number\"` and `\"time\"` format type, the text formatting pattern for labels of guides (axes, legends, headers) and text marks.\n\n- If the format type is `\"number\"` (e.g., for quantitative fields), this is D3's [number format pattern](https://github.com/d3/d3-format#locale_format).\n- If the format type is `\"time\"` (e.g., for temporal fields), this is D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format).\n\nSee the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more examples.\n\nWhen used with a [custom `formatType`](https://vega.github.io/vega-lite/docs/config.html#custom-format-type), this value will be passed as `format` alongside `datum.value` to the registered function.\n\n__Default value:__ Derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for number format and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for time format."
- },
- "formatType": {
- "description": "The format type for labels. One of `\"number\"`, `\"time\"`, or a [registered custom format type](https://vega.github.io/vega-lite/docs/config.html#custom-format-type).\n\n__Default value:__\n- `\"time\"` for temporal fields and ordinal and nominal fields with `timeUnit`.\n- `\"number\"` for quantitative fields as well as ordinal and nominal fields without `timeUnit`.",
- "type": "string"
- },
- "grid": {
- "description": "A boolean flag indicating if grid lines should be included as part of the axis\n\n__Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.",
- "type": "boolean"
- },
- "gridCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for grid lines' ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "gridColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of gridlines.\n\n__Default value:__ `\"lightGray\"`."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "gridDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed grid lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumberArray"
- }
- ]
- },
- "gridDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the grid dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "gridOpacity": {
- "anyOf": [
- {
- "description": "The stroke opacity of grid (value between [0,1])\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "gridWidth": {
- "anyOf": [
- {
- "description": "The grid width, in pixels.\n\n__Default value:__ `1`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelAlign": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align",
- "description": "Horizontal text alignment of axis tick labels, overriding the default setting for the current axis orientation."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelAlign"
- }
- ]
- },
- "labelAngle": {
- "anyOf": [
- {
- "description": "The rotation angle of the axis labels.\n\n__Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.",
- "maximum": 360,
- "minimum": -360,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelBaseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline",
- "description": "Vertical text baseline of axis tick labels, overriding the default setting for the current axis orientation. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, or `\"line-bottom\"`. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the *lineHeight* rather than *fontSize* alone."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelBaseline"
- }
- ]
- },
- "labelBound": {
- "anyOf": [
- {
- "description": "Indicates if labels should be hidden if they exceed the axis range. If `false` (the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range.\n\n__Default value:__ `false`.",
- "type": [
- "number",
- "boolean"
- ]
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "The color of the tick label, can be in hex color code or regular color name."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "labelExpr": {
- "description": "[Vega expression](https://vega.github.io/vega/docs/expressions/) for customizing labels.\n\n__Note:__ The label text and value can be assessed via the `label` and `value` properties of the axis's backing `datum` object.",
- "type": "string"
- },
- "labelFlush": {
- "description": "Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n\n__Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.",
- "type": [
- "boolean",
- "number"
- ]
- },
- "labelFlushOffset": {
- "anyOf": [
- {
- "description": "Indicates the number of pixels by which to offset flush-adjusted labels. For example, a value of `2` will push flush-adjusted labels 2 pixels outward from the center of the axis. Offsets can help the labels better visually group with corresponding axis ticks.\n\n__Default value:__ `0`.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelFont": {
- "anyOf": [
- {
- "description": "The font of the tick label.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisString"
- }
- ]
- },
- "labelFontSize": {
- "anyOf": [
- {
- "description": "The font size of the label, in pixels.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelFontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style of the title."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelFontStyle"
- }
- ]
- },
- "labelFontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight of axis tick labels."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelFontWeight"
- }
- ]
- },
- "labelLimit": {
- "anyOf": [
- {
- "description": "Maximum allowed pixel width of axis tick labels.\n\n__Default value:__ `180`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelLineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line label text or label text with `\"line-top\"` or `\"line-bottom\"` baseline.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelOffset": {
- "anyOf": [
- {
- "description": "Position offset in pixels to apply to labels, in addition to tickOffset.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelOpacity": {
- "anyOf": [
- {
- "description": "The opacity of the labels.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelOverlap": {
- "anyOf": [
- {
- "$ref": "#/definitions/LabelOverlap"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n\n__Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`."
- },
- "labelPadding": {
- "anyOf": [
- {
- "description": "The padding in pixels between labels and ticks.\n\n__Default value:__ `2`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelSeparation": {
- "anyOf": [
- {
- "description": "The minimum separation that must be between label bounding boxes for them to be considered non-overlapping (default `0`). This property is ignored if *labelOverlap* resolution is not enabled.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labels": {
- "description": "A boolean flag indicating if labels should be included as part of the axis.\n\n__Default value:__ `true`.",
- "type": "boolean"
- },
- "maxExtent": {
- "anyOf": [
- {
- "description": "The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n\n__Default value:__ `undefined`.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "minExtent": {
- "anyOf": [
- {
- "description": "The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n\n__Default value:__ `30` for y-axis; `undefined` for x-axis.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "offset": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n\n__Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)"
- },
- "orient": {
- "anyOf": [
- {
- "$ref": "#/definitions/AxisOrient"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y-axis oriented towards the right edge of the chart).\n\n__Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes."
- },
- "position": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The anchor position of the axis in pixels. For x-axes with top or bottom orientation, this sets the axis group x coordinate. For y-axes with left or right orientation, this sets the axis group y coordinate.\n\n__Default value__: `0`"
- },
- "style": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- ],
- "description": "A string or array of strings indicating the name of custom styles to apply to the axis. A style is a named collection of axis property defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles.\n\n__Default value:__ (none) __Note:__ Any specified style will augment the default style. For example, an x-axis mark with `\"style\": \"foo\"` will use `config.axisX` and `config.style.foo` (the specified style `\"foo\"` has higher precedence)."
- },
- "tickBand": {
- "anyOf": [
- {
- "description": "For band scales, indicates if ticks and grid lines should be placed at the `\"center\"` of a band (default) or at the band `\"extent\"`s to indicate intervals",
- "enum": [
- "center",
- "extent"
- ],
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for the tick lines' ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "The color of the axis's tick.\n\n__Default value:__ `\"gray\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "tickCount": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/TimeInterval"
- },
- {
- "$ref": "#/definitions/TimeIntervalStep"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n\nFor scales of type `\"time\"` or `\"utc\"`, the tick count can instead be a time interval specifier. Legal string values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}` includes a desired number of interval steps. Here, ticks are generated for each quarter (Jan, Apr, Jul, Oct) boundary.\n\n__Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.",
- "minimum": 0
- },
- "tickDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed tick mark lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumberArray"
- }
- ]
- },
- "tickDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the tick mark dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickExtra": {
- "description": "Boolean flag indicating if an extra axis tick should be added for the initial position of the axis. This flag is useful for styling axes for `band` scales such that ticks are placed on band boundaries rather in the middle of a band. Use in conjunction with `\"bandPosition\": 1` and an axis `\"padding\"` value of `0`.",
- "type": "boolean"
- },
- "tickMinStep": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The minimum desired step between axis ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value."
- },
- "tickOffset": {
- "anyOf": [
- {
- "description": "Position offset in pixels to apply to ticks, labels, and gridlines.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the ticks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickRound": {
- "description": "Boolean flag indicating if pixel position values should be rounded to the nearest integer.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "tickSize": {
- "anyOf": [
- {
- "description": "The size in pixels of axis ticks.\n\n__Default value:__ `5`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickWidth": {
- "anyOf": [
- {
- "description": "The width, in pixels, of ticks.\n\n__Default value:__ `1`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "ticks": {
- "description": "Boolean value that determines whether the axis should include ticks.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "title": {
- "anyOf": [
- {
- "$ref": "#/definitions/Text"
- },
- {
- "type": "null"
- }
- ],
- "description": "A title for the field. If `null`, the title will be removed.\n\n__Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n\n__Notes__:\n\n1) You can customize the default field title format by providing the [`fieldTitle`](https://vega.github.io/vega-lite/docs/config.html#top-level-config) property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/usage/compile.html#field-title).\n\n2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used."
- },
- "titleAlign": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align",
- "description": "Horizontal text alignment of axis titles."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleAnchor": {
- "anyOf": [
- {
- "$ref": "#/definitions/TitleAnchor",
- "description": "Text anchor position for placing axis titles."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleAngle": {
- "anyOf": [
- {
- "description": "Angle in degrees of axis titles.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleBaseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline",
- "description": "Vertical text baseline for axis titles. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, or `\"line-bottom\"`. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the *lineHeight* rather than *fontSize* alone."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of the title, can be in hex color code or regular color name."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFont": {
- "anyOf": [
- {
- "description": "Font of the title. (e.g., `\"Helvetica Neue\"`).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontSize": {
- "anyOf": [
- {
- "description": "Font size of the title.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style of the title."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight of the title. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleLimit": {
- "anyOf": [
- {
- "description": "Maximum allowed pixel width of axis titles.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleLineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line title text or title text with `\"line-top\"` or `\"line-bottom\"` baseline.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the axis title.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titlePadding": {
- "anyOf": [
- {
- "description": "The padding, in pixels, between title and axis.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleX": {
- "anyOf": [
- {
- "description": "X-coordinate of the axis title relative to the axis group.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleY": {
- "anyOf": [
- {
- "description": "Y-coordinate of the axis title relative to the axis group.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "translate": {
- "anyOf": [
- {
- "description": "Coordinate space translation offset for axis layout. By default, axes are translated by a 0.5 pixel offset for both the x and y coordinates in order to align stroked lines with the pixel grid. However, for vector graphics output these pixel-specific adjustments may be undesirable, in which case translate can be changed (for example, to zero).\n\n__Default value:__ `0.5`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "values": {
- "anyOf": [
- {
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "items": {
- "type": "boolean"
- },
- "type": "array"
- },
- {
- "items": {
- "$ref": "#/definitions/DateTime"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Explicitly set the visible axis tick values."
- },
- "zindex": {
- "description": "A non-negative integer indicating the z-index of the axis. If zindex is 0, axes should be drawn behind all chart elements. To put them in front, set `zindex` to `1` or more.\n\n__Default value:__ `0` (behind the marks).",
- "minimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- },
- "AxisConfig": {
- "additionalProperties": false,
- "properties": {
- "aria": {
- "anyOf": [
- {
- "description": "A boolean flag indicating if [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) should be included (SVG output only). If `false`, the \"aria-hidden\" attribute will be set on the output SVG group, removing the axis from the ARIA accessibility tree.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "bandPosition": {
- "anyOf": [
- {
- "description": "An interpolation fraction indicating where, for `band` scales, axis ticks should be positioned. A value of `0` places ticks at the left edge of their bands. A value of `0.5` places ticks in the middle of their bands.\n\n __Default value:__ `0.5`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "description": {
- "anyOf": [
- {
- "description": "A text description of this axis for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If the `aria` property is true, for SVG output the [\"aria-label\" attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) will be set to this description. If the description is unspecified it will be automatically generated.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "disable": {
- "description": "Disable axis by default.",
- "type": "boolean"
- },
- "domain": {
- "description": "A boolean flag indicating if the domain (the axis baseline) should be included as part of the axis.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "domainCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for the domain line's ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of axis domain line.\n\n__Default value:__ `\"gray\"`."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed domain lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the domain dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the axis domain line.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "domainWidth": {
- "anyOf": [
- {
- "description": "Stroke width of axis domain line\n\n__Default value:__ `1`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "format": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "$ref": "#/definitions/Dict"
- }
- ],
- "description": "When used with the default `\"number\"` and `\"time\"` format type, the text formatting pattern for labels of guides (axes, legends, headers) and text marks.\n\n- If the format type is `\"number\"` (e.g., for quantitative fields), this is D3's [number format pattern](https://github.com/d3/d3-format#locale_format).\n- If the format type is `\"time\"` (e.g., for temporal fields), this is D3's [time format pattern](https://github.com/d3/d3-time-format#locale_format).\n\nSee the [format documentation](https://vega.github.io/vega-lite/docs/format.html) for more examples.\n\nWhen used with a [custom `formatType`](https://vega.github.io/vega-lite/docs/config.html#custom-format-type), this value will be passed as `format` alongside `datum.value` to the registered function.\n\n__Default value:__ Derived from [numberFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for number format and from [timeFormat](https://vega.github.io/vega-lite/docs/config.html#format) config for time format."
- },
- "formatType": {
- "description": "The format type for labels. One of `\"number\"`, `\"time\"`, or a [registered custom format type](https://vega.github.io/vega-lite/docs/config.html#custom-format-type).\n\n__Default value:__\n- `\"time\"` for temporal fields and ordinal and nominal fields with `timeUnit`.\n- `\"number\"` for quantitative fields as well as ordinal and nominal fields without `timeUnit`.",
- "type": "string"
- },
- "grid": {
- "description": "A boolean flag indicating if grid lines should be included as part of the axis\n\n__Default value:__ `true` for [continuous scales](https://vega.github.io/vega-lite/docs/scale.html#continuous) that are not binned; otherwise, `false`.",
- "type": "boolean"
- },
- "gridCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for grid lines' ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "gridColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of gridlines.\n\n__Default value:__ `\"lightGray\"`."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "gridDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed grid lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumberArray"
- }
- ]
- },
- "gridDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the grid dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "gridOpacity": {
- "anyOf": [
- {
- "description": "The stroke opacity of grid (value between [0,1])\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "gridWidth": {
- "anyOf": [
- {
- "description": "The grid width, in pixels.\n\n__Default value:__ `1`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelAlign": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align",
- "description": "Horizontal text alignment of axis tick labels, overriding the default setting for the current axis orientation."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelAlign"
- }
- ]
- },
- "labelAngle": {
- "anyOf": [
- {
- "description": "The rotation angle of the axis labels.\n\n__Default value:__ `-90` for nominal and ordinal fields; `0` otherwise.",
- "maximum": 360,
- "minimum": -360,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelBaseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline",
- "description": "Vertical text baseline of axis tick labels, overriding the default setting for the current axis orientation. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, or `\"line-bottom\"`. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the *lineHeight* rather than *fontSize* alone."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelBaseline"
- }
- ]
- },
- "labelBound": {
- "anyOf": [
- {
- "description": "Indicates if labels should be hidden if they exceed the axis range. If `false` (the default) no bounds overlap analysis is performed. If `true`, labels will be hidden if they exceed the axis range by more than 1 pixel. If this property is a number, it specifies the pixel tolerance: the maximum amount by which a label bounding box may exceed the axis range.\n\n__Default value:__ `false`.",
- "type": [
- "number",
- "boolean"
- ]
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "The color of the tick label, can be in hex color code or regular color name."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "labelExpr": {
- "description": "[Vega expression](https://vega.github.io/vega/docs/expressions/) for customizing labels.\n\n__Note:__ The label text and value can be assessed via the `label` and `value` properties of the axis's backing `datum` object.",
- "type": "string"
- },
- "labelFlush": {
- "description": "Indicates if the first and last axis labels should be aligned flush with the scale range. Flush alignment for a horizontal axis will left-align the first label and right-align the last label. For vertical axes, bottom and top text baselines are applied instead. If this property is a number, it also indicates the number of pixels by which to offset the first and last labels; for example, a value of 2 will flush-align the first and last labels and also push them 2 pixels outward from the center of the axis. The additional adjustment can sometimes help the labels better visually group with corresponding axis ticks.\n\n__Default value:__ `true` for axis of a continuous x-scale. Otherwise, `false`.",
- "type": [
- "boolean",
- "number"
- ]
- },
- "labelFlushOffset": {
- "anyOf": [
- {
- "description": "Indicates the number of pixels by which to offset flush-adjusted labels. For example, a value of `2` will push flush-adjusted labels 2 pixels outward from the center of the axis. Offsets can help the labels better visually group with corresponding axis ticks.\n\n__Default value:__ `0`.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelFont": {
- "anyOf": [
- {
- "description": "The font of the tick label.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisString"
- }
- ]
- },
- "labelFontSize": {
- "anyOf": [
- {
- "description": "The font size of the label, in pixels.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelFontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style of the title."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelFontStyle"
- }
- ]
- },
- "labelFontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight of axis tick labels."
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisLabelFontWeight"
- }
- ]
- },
- "labelLimit": {
- "anyOf": [
- {
- "description": "Maximum allowed pixel width of axis tick labels.\n\n__Default value:__ `180`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelLineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line label text or label text with `\"line-top\"` or `\"line-bottom\"` baseline.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labelOffset": {
- "anyOf": [
- {
- "description": "Position offset in pixels to apply to labels, in addition to tickOffset.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelOpacity": {
- "anyOf": [
- {
- "description": "The opacity of the labels.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelOverlap": {
- "anyOf": [
- {
- "$ref": "#/definitions/LabelOverlap"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The strategy to use for resolving overlap of axis labels. If `false` (the default), no overlap reduction is attempted. If set to `true` or `\"parity\"`, a strategy of removing every other label is used (this works well for standard linear axes). If set to `\"greedy\"`, a linear scan of the labels is performed, removing any labels that overlaps with the last visible label (this often works better for log-scaled axes).\n\n__Default value:__ `true` for non-nominal fields with non-log scales; `\"greedy\"` for log scales; otherwise `false`."
- },
- "labelPadding": {
- "anyOf": [
- {
- "description": "The padding in pixels between labels and ticks.\n\n__Default value:__ `2`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "labelSeparation": {
- "anyOf": [
- {
- "description": "The minimum separation that must be between label bounding boxes for them to be considered non-overlapping (default `0`). This property is ignored if *labelOverlap* resolution is not enabled.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "labels": {
- "description": "A boolean flag indicating if labels should be included as part of the axis.\n\n__Default value:__ `true`.",
- "type": "boolean"
- },
- "maxExtent": {
- "anyOf": [
- {
- "description": "The maximum extent in pixels that axis ticks and labels should use. This determines a maximum offset value for axis titles.\n\n__Default value:__ `undefined`.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "minExtent": {
- "anyOf": [
- {
- "description": "The minimum extent in pixels that axis ticks and labels should use. This determines a minimum offset value for axis titles.\n\n__Default value:__ `30` for y-axis; `undefined` for x-axis.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "offset": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The offset, in pixels, by which to displace the axis from the edge of the enclosing group or data rectangle.\n\n__Default value:__ derived from the [axis config](https://vega.github.io/vega-lite/docs/config.html#facet-scale-config)'s `offset` (`0` by default)"
- },
- "orient": {
- "anyOf": [
- {
- "$ref": "#/definitions/AxisOrient"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The orientation of the axis. One of `\"top\"`, `\"bottom\"`, `\"left\"` or `\"right\"`. The orientation can be used to further specialize the axis type (e.g., a y-axis oriented towards the right edge of the chart).\n\n__Default value:__ `\"bottom\"` for x-axes and `\"left\"` for y-axes."
- },
- "position": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The anchor position of the axis in pixels. For x-axes with top or bottom orientation, this sets the axis group x coordinate. For y-axes with left or right orientation, this sets the axis group y coordinate.\n\n__Default value__: `0`"
- },
- "style": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- }
- ],
- "description": "A string or array of strings indicating the name of custom styles to apply to the axis. A style is a named collection of axis property defined within the [style configuration](https://vega.github.io/vega-lite/docs/mark.html#style-config). If style is an array, later styles will override earlier styles.\n\n__Default value:__ (none) __Note:__ Any specified style will augment the default style. For example, an x-axis mark with `\"style\": \"foo\"` will use `config.axisX` and `config.style.foo` (the specified style `\"foo\"` has higher precedence)."
- },
- "tickBand": {
- "anyOf": [
- {
- "description": "For band scales, indicates if ticks and grid lines should be placed at the `\"center\"` of a band (default) or at the band `\"extent\"`s to indicate intervals",
- "enum": [
- "center",
- "extent"
- ],
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for the tick lines' ending style. One of `\"butt\"`, `\"round\"` or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "The color of the axis's tick.\n\n__Default value:__ `\"gray\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisColor"
- }
- ]
- },
- "tickCount": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/TimeInterval"
- },
- {
- "$ref": "#/definitions/TimeIntervalStep"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "A desired number of ticks, for axes visualizing quantitative scales. The resulting number may be different so that values are \"nice\" (multiples of 2, 5, 10) and lie within the underlying scale's range.\n\nFor scales of type `\"time\"` or `\"utc\"`, the tick count can instead be a time interval specifier. Legal string values are `\"millisecond\"`, `\"second\"`, `\"minute\"`, `\"hour\"`, `\"day\"`, `\"week\"`, `\"month\"`, and `\"year\"`. Alternatively, an object-valued interval specifier of the form `{\"interval\": \"month\", \"step\": 3}` includes a desired number of interval steps. Here, ticks are generated for each quarter (Jan, Apr, Jul, Oct) boundary.\n\n__Default value__: Determine using a formula `ceil(width/40)` for x and `ceil(height/40)` for y.",
- "minimum": 0
- },
- "tickDash": {
- "anyOf": [
- {
- "description": "An array of alternating [stroke, space] lengths for dashed tick mark lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumberArray"
- }
- ]
- },
- "tickDashOffset": {
- "anyOf": [
- {
- "description": "The pixel offset at which to start drawing with the tick mark dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickExtra": {
- "description": "Boolean flag indicating if an extra axis tick should be added for the initial position of the axis. This flag is useful for styling axes for `band` scales such that ticks are placed on band boundaries rather in the middle of a band. Use in conjunction with `\"bandPosition\": 1` and an axis `\"padding\"` value of `0`.",
- "type": "boolean"
- },
- "tickMinStep": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The minimum desired step between axis ticks, in terms of scale domain values. For example, a value of `1` indicates that ticks should not be less than 1 unit apart. If `tickMinStep` is specified, the `tickCount` value will be adjusted, if necessary, to enforce the minimum step value."
- },
- "tickOffset": {
- "anyOf": [
- {
- "description": "Position offset in pixels to apply to ticks, labels, and gridlines.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tickOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the ticks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickRound": {
- "description": "Boolean flag indicating if pixel position values should be rounded to the nearest integer.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "tickSize": {
- "anyOf": [
- {
- "description": "The size in pixels of axis ticks.\n\n__Default value:__ `5`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "tickWidth": {
- "anyOf": [
- {
- "description": "The width, in pixels, of ticks.\n\n__Default value:__ `1`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "$ref": "#/definitions/ConditionalAxisNumber"
- }
- ]
- },
- "ticks": {
- "description": "Boolean value that determines whether the axis should include ticks.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "title": {
- "anyOf": [
- {
- "$ref": "#/definitions/Text"
- },
- {
- "type": "null"
- }
- ],
- "description": "A title for the field. If `null`, the title will be removed.\n\n__Default value:__ derived from the field's name and transformation function (`aggregate`, `bin` and `timeUnit`). If the field has an aggregate function, the function is displayed as part of the title (e.g., `\"Sum of Profit\"`). If the field is binned or has a time unit applied, the applied function is shown in parentheses (e.g., `\"Profit (binned)\"`, `\"Transaction Date (year-month)\"`). Otherwise, the title is simply the field name.\n\n__Notes__:\n\n1) You can customize the default field title format by providing the [`fieldTitle`](https://vega.github.io/vega-lite/docs/config.html#top-level-config) property in the [config](https://vega.github.io/vega-lite/docs/config.html) or [`fieldTitle` function via the `compile` function's options](https://vega.github.io/vega-lite/usage/compile.html#field-title).\n\n2) If both field definition's `title` and axis, header, or legend `title` are defined, axis/header/legend title will be used."
- },
- "titleAlign": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align",
- "description": "Horizontal text alignment of axis titles."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleAnchor": {
- "anyOf": [
- {
- "$ref": "#/definitions/TitleAnchor",
- "description": "Text anchor position for placing axis titles."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleAngle": {
- "anyOf": [
- {
- "description": "Angle in degrees of axis titles.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleBaseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline",
- "description": "Vertical text baseline for axis titles. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, or `\"line-bottom\"`. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the *lineHeight* rather than *fontSize* alone."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Color of the title, can be in hex color code or regular color name."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFont": {
- "anyOf": [
- {
- "description": "Font of the title. (e.g., `\"Helvetica Neue\"`).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontSize": {
- "anyOf": [
- {
- "description": "Font size of the title.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style of the title."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleFontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight of the title. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleLimit": {
- "anyOf": [
- {
- "description": "Maximum allowed pixel width of axis titles.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleLineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line title text or title text with `\"line-top\"` or `\"line-bottom\"` baseline.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleOpacity": {
- "anyOf": [
- {
- "description": "Opacity of the axis title.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titlePadding": {
- "anyOf": [
- {
- "description": "The padding, in pixels, between title and axis.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleX": {
- "anyOf": [
- {
- "description": "X-coordinate of the axis title relative to the axis group.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "titleY": {
- "anyOf": [
- {
- "description": "Y-coordinate of the axis title relative to the axis group.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "translate": {
- "anyOf": [
- {
- "description": "Coordinate space translation offset for axis layout. By default, axes are translated by a 0.5 pixel offset for both the x and y coordinates in order to align stroked lines with the pixel grid. However, for vector graphics output these pixel-specific adjustments may be undesirable, in which case translate can be changed (for example, to zero).\n\n__Default value:__ `0.5`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "values": {
- "anyOf": [
- {
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "items": {
- "type": "boolean"
- },
- "type": "array"
- },
- {
- "items": {
- "$ref": "#/definitions/DateTime"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Explicitly set the visible axis tick values."
- },
- "zindex": {
- "description": "A non-negative integer indicating the z-index of the axis. If zindex is 0, axes should be drawn behind all chart elements. To put them in front, set `zindex` to `1` or more.\n\n__Default value:__ `0` (behind the marks).",
- "minimum": 0,
- "type": "number"
- }
- },
- "type": "object"
- },
- "AxisOrient": {
- "enum": [
- "top",
- "bottom",
- "left",
- "right"
- ],
- "type": "string"
- },
- "AxisResolveMap": {
- "additionalProperties": false,
- "properties": {
- "x": {
- "$ref": "#/definitions/ResolveMode"
- },
- "y": {
- "$ref": "#/definitions/ResolveMode"
- }
- },
- "type": "object"
- },
- "BBox": {
- "anyOf": [
- {
- "items": {
- "type": "number"
- },
- "maxItems": 4,
- "minItems": 4,
- "type": "array"
- },
- {
- "items": {
- "type": "number"
- },
- "maxItems": 6,
- "minItems": 6,
- "type": "array"
- }
- ],
- "description": "Bounding box https://tools.ietf.org/html/rfc7946#section-5"
- },
- "BarConfig": {
- "additionalProperties": false,
- "properties": {
- "align": {
- "anyOf": [
- {
- "$ref": "#/definitions/Align"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). One of `\"left\"`, `\"right\"`, `\"center\"`.\n\n__Note:__ Expression reference is *not* supported for range marks."
- },
- "angle": {
- "anyOf": [
- {
- "description": "The rotation angle of the text, in degrees.",
- "maximum": 360,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "aria": {
- "anyOf": [
- {
- "description": "A boolean flag indicating if [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) should be included (SVG output only). If `false`, the \"aria-hidden\" attribute will be set on the output SVG element, removing the mark item from the ARIA accessibility tree.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ariaRole": {
- "anyOf": [
- {
- "description": "Sets the type of user interface element of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the \"role\" attribute. Warning: this property is experimental and may be changed in the future.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ariaRoleDescription": {
- "anyOf": [
- {
- "description": "A human-readable, author-localized description for the role of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the \"aria-roledescription\" attribute. Warning: this property is experimental and may be changed in the future.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "aspect": {
- "anyOf": [
- {
- "description": "Whether to keep aspect ratio of image marks.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "baseline": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextBaseline"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "For text marks, the vertical text baseline. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, `\"line-bottom\"`, or an expression reference that provides one of the valid values. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the `lineHeight` rather than `fontSize` alone.\n\nFor range marks, the vertical alignment of the marks. One of `\"top\"`, `\"middle\"`, `\"bottom\"`.\n\n__Note:__ Expression reference is *not* supported for range marks."
- },
- "binSpacing": {
- "description": "Offset between bars for binned field. The ideal value for this is either 0 (preferred by statisticians) or 1 (Vega-Lite default, D3 example style).\n\n__Default value:__ `1`",
- "minimum": 0,
- "type": "number"
- },
- "blend": {
- "anyOf": [
- {
- "$ref": "#/definitions/Blend",
- "description": "The color blend mode for drawing an item on its current background. Any valid [CSS mix-blend-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode) value can be used.\n\n__Default value: `\"source-over\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "color": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default color.\n\n__Default value:__ ■ `\"#4682b4\"`\n\n__Note:__\n- This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n- The `fill` and `stroke` properties have higher precedence than `color` and will override `color`."
- },
- "continuousBandSize": {
- "description": "The default size of the bars on continuous scales.\n\n__Default value:__ `5`",
- "minimum": 0,
- "type": "number"
- },
- "cornerRadius": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles or arcs' corners.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusBottomLeft": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' bottom left corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusBottomRight": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' bottom right corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusEnd": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "- For vertical bars, top-left and top-right corner radius.\n\n- For horizontal bars, top-right and bottom-right corner radius."
- },
- "cornerRadiusTopLeft": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' top right corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cornerRadiusTopRight": {
- "anyOf": [
- {
- "description": "The radius in pixels of rounded rectangles' top left corner.\n\n__Default value:__ `0`",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "cursor": {
- "anyOf": [
- {
- "$ref": "#/definitions/Cursor",
- "description": "The mouse cursor used over the mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "description": {
- "anyOf": [
- {
- "description": "A text description of the mark item for [ARIA accessibility](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) (SVG output only). If specified, this property determines the [\"aria-label\" attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dir": {
- "anyOf": [
- {
- "$ref": "#/definitions/TextDirection",
- "description": "The direction of the text. One of `\"ltr\"` (left-to-right) or `\"rtl\"` (right-to-left). This property determines on which side is truncated in response to the limit parameter.\n\n__Default value:__ `\"ltr\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "discreteBandSize": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/RelativeBandSize"
- }
- ],
- "description": "The default size of the bars with discrete dimensions. If unspecified, the default size is `step-2`, which provides 2 pixel offset between bars.",
- "minimum": 0
- },
- "dx": {
- "anyOf": [
- {
- "description": "The horizontal offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dy": {
- "anyOf": [
- {
- "description": "The vertical offset, in pixels, between the text label and its anchor point. The offset is applied after rotation by the _angle_ property.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "ellipsis": {
- "anyOf": [
- {
- "description": "The ellipsis string for text truncated in response to the limit parameter.\n\n__Default value:__ `\"…\"`",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "endAngle": {
- "anyOf": [
- {
- "description": "The end angle in radians for arc marks. A value of `0` indicates up (north), increasing values proceed clockwise.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fill": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default fill color. This property has higher precedence than `config.color`. Set to `null` to remove fill.\n\n__Default value:__ (None)"
- },
- "fillOpacity": {
- "anyOf": [
- {
- "description": "The fill opacity (value between [0,1]).\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "filled": {
- "description": "Whether the mark's color should be used as fill color instead of stroke color.\n\n__Default value:__ `false` for all `point`, `line`, and `rule` marks as well as `geoshape` marks for [`graticule`](https://vega.github.io/vega-lite/docs/data.html#graticule) data sources; otherwise, `true`.\n\n__Note:__ This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).",
- "type": "boolean"
- },
- "font": {
- "anyOf": [
- {
- "description": "The typeface to set the text in (e.g., `\"Helvetica Neue\"`).",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontSize": {
- "anyOf": [
- {
- "description": "The font size, in pixels.\n\n__Default value:__ `11`",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "The font style (e.g., `\"italic\"`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "The font weight. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "height": {
- "anyOf": [
- {
- "description": "Height of the marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "href": {
- "anyOf": [
- {
- "$ref": "#/definitions/URI",
- "description": "A URL to load upon mouse click. If defined, the mark acts as a hyperlink."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "innerRadius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The inner radius in pixels of arc marks. `innerRadius` is an alias for `radius2`.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "interpolate": {
- "anyOf": [
- {
- "$ref": "#/definitions/Interpolate",
- "description": "The line interpolation method to use for line and area marks. One of the following:\n- `\"linear\"`: piecewise linear segments, as in a polyline.\n- `\"linear-closed\"`: close the linear segments to form a polygon.\n- `\"step\"`: alternate between horizontal and vertical segments, as in a step function.\n- `\"step-before\"`: alternate between vertical and horizontal segments, as in a step function.\n- `\"step-after\"`: alternate between horizontal and vertical segments, as in a step function.\n- `\"basis\"`: a B-spline, with control point duplication on the ends.\n- `\"basis-open\"`: an open B-spline; may not intersect the start or end.\n- `\"basis-closed\"`: a closed B-spline, as in a loop.\n- `\"cardinal\"`: a Cardinal spline, with control point duplication on the ends.\n- `\"cardinal-open\"`: an open Cardinal spline; may not intersect the start or end, but will intersect other control points.\n- `\"cardinal-closed\"`: a closed Cardinal spline, as in a loop.\n- `\"bundle\"`: equivalent to basis, except the tension parameter is used to straighten the spline.\n- `\"monotone\"`: cubic interpolation that preserves monotonicity in y."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "invalid": {
- "anyOf": [
- {
- "$ref": "#/definitions/MarkInvalidDataMode"
- },
- {
- "type": "null"
- }
- ],
- "description": "Invalid data mode, which defines how the marks and corresponding scales should represent invalid values (`null` and `NaN` in continuous scales *without* defined output for invalid values).\n\n- `\"filter\"` — *Exclude* all invalid values from the visualization's *marks* and *scales*. For path marks (for line, area, trail), this option will create paths that connect valid points, as if the data rows with invalid values do not exist.\n\n- `\"break-paths-filter-domains\"` — Break path marks (for line, area, trail) at invalid values. For non-path marks, this is equivalent to `\"filter\"`. All *scale* domains will *exclude* these filtered data points.\n\n- `\"break-paths-show-domains\"` — Break paths (for line, area, trail) at invalid values. Hide invalid values for non-path marks. All *scale* domains will *include* these filtered data points (for both path and non-path marks).\n\n- `\"show\"` or `null` — Show all data points in the marks and scale domains. Each scale will use the output for invalid values defined in `config.scale.invalid` or, if unspecified, by default invalid values will produce the same visual values as zero (if the scale includes zero) or the minimum value (if the scale does not include zero).\n\n- `\"break-paths-show-path-domains\"` (default) — This is equivalent to `\"break-paths-show-domains\"` for path-based marks (line/area/trail) and `\"filter\"` for non-path marks.\n\n__Note__: If any channel's scale has an output for invalid values defined in `config.scale.invalid`, all values for the scales will be considered \"valid\" since they can produce a reasonable output for the scales. Thus, fields for such channels will not be filtered and will not cause path breaks."
- },
- "limit": {
- "anyOf": [
- {
- "description": "The maximum length of the text mark in pixels. The text value will be automatically truncated if the rendered size exceeds the limit.\n\n__Default value:__ `0` -- indicating no limit",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "lineBreak": {
- "anyOf": [
- {
- "description": "A delimiter, such as a newline character, upon which to break text strings into multiple lines. This property is ignored if the text is array-valued.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "lineHeight": {
- "anyOf": [
- {
- "description": "The line height in pixels (the spacing between subsequent lines of text) for multi-line text marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "minBandSize": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The minimum band size for bar and rectangle marks. __Default value:__ `0.25`"
- },
- "opacity": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The overall opacity (value between [0,1]).\n\n__Default value:__ `0.7` for non-aggregate plots with `point`, `tick`, `circle`, or `square` marks or layered `bar` charts and `1` otherwise.",
- "maximum": 1,
- "minimum": 0
- },
- "order": {
- "description": "For line and trail marks, this `order` property can be set to `null` or `false` to make the lines use the original order in the data sources.",
- "type": [
- "null",
- "boolean"
- ]
- },
- "orient": {
- "$ref": "#/definitions/Orientation",
- "description": "The orientation of a non-stacked bar, tick, area, and line charts. The value is either horizontal (default) or vertical.\n- For bar, rule and tick, this determines whether the size of the bar and tick should be applied to x or y dimension.\n- For area, this property determines the orient property of the Vega output.\n- For line and trail marks, this property determines the sort order of the points in the line if `config.sortLineBy` is not specified. For stacked charts, this is always determined by the orientation of the stack; therefore explicitly specified value will be ignored."
- },
- "outerRadius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The outer radius in pixels of arc marks. `outerRadius` is an alias for `radius`.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "padAngle": {
- "anyOf": [
- {
- "description": "The angular padding applied to sides of the arc, in radians.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "radius": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "For arc mark, the primary (outer) radius in pixels.\n\nFor text marks, polar coordinate radial offset, in pixels, of the text from the origin determined by the `x` and `y` properties.\n\n__Default value:__ `min(plot_width, plot_height)/2`",
- "minimum": 0
- },
- "radius2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The secondary (inner) radius in pixels of arc marks.\n\n__Default value:__ `0`",
- "minimum": 0
- },
- "shape": {
- "anyOf": [
- {
- "anyOf": [
- {
- "$ref": "#/definitions/SymbolShape"
- },
- {
- "type": "string"
- }
- ],
- "description": "Shape of the point marks. Supported values include:\n- plotting shapes: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, `\"triangle-down\"`, `\"triangle-right\"`, or `\"triangle-left\"`.\n- the line symbol `\"stroke\"`\n- centered directional shapes `\"arrow\"`, `\"wedge\"`, or `\"triangle\"`\n- a custom [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.)\n\n__Default value:__ `\"circle\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "size": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default size for marks.\n- For `point`/`circle`/`square`, this represents the pixel area of the marks. Note that this value sets the area of the symbol; the side lengths will increase with the square root of this value.\n- For `bar`, this represents the band size of the bar, in pixels.\n- For `text`, this represents the font size, in pixels.\n\n__Default value:__\n- `30` for point, circle, square marks; width/height's `step`\n- `2` for bar marks with discrete dimensions;\n- `5` for bar marks with continuous dimensions;\n- `11` for text marks.",
- "minimum": 0
- },
- "smooth": {
- "anyOf": [
- {
- "description": "A boolean flag (default true) indicating if the image should be smoothed when resized. If false, individual pixels should be scaled directly rather than interpolated with smoothing. For SVG rendering, this option may not work in some browsers due to lack of standardization.",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "startAngle": {
- "anyOf": [
- {
- "description": "The start angle in radians for arc marks. A value of `0` indicates up (north), increasing values proceed clockwise.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "stroke": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default stroke color. This property has higher precedence than `config.color`. Set to `null` to remove stroke.\n\n__Default value:__ (None)"
- },
- "strokeCap": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeCap",
- "description": "The stroke cap for line ending style. One of `\"butt\"`, `\"round\"`, or `\"square\"`.\n\n__Default value:__ `\"butt\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeDash": {
- "anyOf": [
- {
- "description": "An array of alternating stroke, space lengths for creating dashed or dotted lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeDashOffset": {
- "anyOf": [
- {
- "description": "The offset (in pixels) into which to begin drawing with the stroke dash array.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeJoin": {
- "anyOf": [
- {
- "$ref": "#/definitions/StrokeJoin",
- "description": "The stroke line join method. One of `\"miter\"`, `\"round\"` or `\"bevel\"`.\n\n__Default value:__ `\"miter\"`"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeMiterLimit": {
- "anyOf": [
- {
- "description": "The miter limit at which to bevel a line join.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeOffset": {
- "anyOf": [
- {
- "description": "The offset in pixels at which to draw the group stroke and fill. If unspecified, the default behavior is to dynamically offset stroked groups such that 1 pixel stroke widths align with the pixel grid.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeOpacity": {
- "anyOf": [
- {
- "description": "The stroke opacity (value between [0,1]).\n\n__Default value:__ `1`",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "strokeWidth": {
- "anyOf": [
- {
- "description": "The stroke width, in pixels.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "tension": {
- "anyOf": [
- {
- "description": "Depending on the interpolation type, sets the tension parameter (for line and area marks).",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "text": {
- "anyOf": [
- {
- "$ref": "#/definitions/Text",
- "description": "Placeholder text if the `text` channel is not specified"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "theta": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "- For arc marks, the arc length in radians if theta2 is not specified, otherwise the start arc angle. (A value of 0 indicates up or “north”, increasing values proceed clockwise.)\n\n- For text marks, polar coordinate angle in radians.",
- "maximum": 360,
- "minimum": 0
- },
- "theta2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "The end angle of arc marks in radians. A value of 0 indicates up or “north”, increasing values proceed clockwise."
- },
- "time": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "timeUnitBandPosition": {
- "description": "Default relative band position for a time unit. If set to `0`, the marks will be positioned at the beginning of the time unit band step. If set to `0.5`, the marks will be positioned in the middle of the time unit band step.",
- "type": "number"
- },
- "timeUnitBandSize": {
- "description": "Default relative band size for a time unit. If set to `1`, the bandwidth of the marks will be equal to the time unit band step. If set to `0.5`, bandwidth of the marks will be half of the time unit band step.",
- "type": "number"
- },
- "tooltip": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "type": "string"
- },
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/TooltipContent"
- },
- {
- "$ref": "#/definitions/ExprRef"
- },
- {
- "type": "null"
- }
- ],
- "description": "The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from.\n\n- If `tooltip` is `true` or `{\"content\": \"encoding\"}`, then all fields from `encoding` will be used.\n- If `tooltip` is `{\"content\": \"data\"}`, then all fields that appear in the highlighted data point will be used.\n- If set to `null` or `false`, then no tooltip will be used.\n\nSee the [`tooltip`](https://vega.github.io/vega-lite/docs/tooltip.html) documentation for a detailed discussion about tooltip in Vega-Lite.\n\n__Default value:__ `null`"
- },
- "url": {
- "anyOf": [
- {
- "$ref": "#/definitions/URI",
- "description": "The URL of the image file for image marks."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "width": {
- "anyOf": [
- {
- "description": "Width of the marks.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "x": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "width",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"` without specified `x2` or `width`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "x2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "width",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "y": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "height",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"` without specified `y2` or `height`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- },
- "y2": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "const": "height",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- }
- },
- "type": "object"
- },
- "BaseTitleNoValueRefs": {
- "additionalProperties": false,
- "properties": {
- "align": {
- "$ref": "#/definitions/Align",
- "description": "Horizontal text alignment for title text. One of `\"left\"`, `\"center\"`, or `\"right\"`."
- },
- "anchor": {
- "anyOf": [
- {
- "$ref": "#/definitions/TitleAnchor",
- "description": "The anchor position for placing the title and subtitle text. One of `\"start\"`, `\"middle\"`, or `\"end\"`. For example, with an orientation of top these anchor positions map to a left-, center-, or right-aligned title."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "angle": {
- "anyOf": [
- {
- "description": "Angle in degrees of title and subtitle text.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "aria": {
- "anyOf": [
- {
- "description": "A boolean flag indicating if [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) should be included (SVG output only). If `false`, the \"aria-hidden\" attribute will be set on the output SVG group, removing the title from the ARIA accessibility tree.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "baseline": {
- "$ref": "#/definitions/TextBaseline",
- "description": "Vertical text baseline for title and subtitle text. One of `\"alphabetic\"` (default), `\"top\"`, `\"middle\"`, `\"bottom\"`, `\"line-top\"`, or `\"line-bottom\"`. The `\"line-top\"` and `\"line-bottom\"` values operate similarly to `\"top\"` and `\"bottom\"`, but are calculated relative to the *lineHeight* rather than *fontSize* alone."
- },
- "color": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Text color for title text."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dx": {
- "anyOf": [
- {
- "description": "Delta offset for title and subtitle text x-coordinate.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "dy": {
- "anyOf": [
- {
- "description": "Delta offset for title and subtitle text y-coordinate.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "font": {
- "anyOf": [
- {
- "description": "Font name for title text.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontSize": {
- "anyOf": [
- {
- "description": "Font size in pixels for title text.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style for title text."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "fontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight for title text. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "frame": {
- "anyOf": [
- {
- "anyOf": [
- {
- "$ref": "#/definitions/TitleFrame"
- },
- {
- "type": "string"
- }
- ],
- "description": "The reference frame for the anchor position, one of `\"bounds\"` (to anchor relative to the full bounding box) or `\"group\"` (to anchor relative to the group width or height)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "limit": {
- "anyOf": [
- {
- "description": "The maximum allowed length in pixels of title and subtitle text.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "lineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line title text or title text with `\"line-top\"` or `\"line-bottom\"` baseline.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "offset": {
- "anyOf": [
- {
- "description": "The orthogonal offset in pixels by which to displace the title group from its position along the edge of the chart.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "orient": {
- "anyOf": [
- {
- "$ref": "#/definitions/TitleOrient",
- "description": "Default title orientation (`\"top\"`, `\"bottom\"`, `\"left\"`, or `\"right\"`)"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleColor": {
- "anyOf": [
- {
- "anyOf": [
- {
- "type": "null"
- },
- {
- "$ref": "#/definitions/Color"
- }
- ],
- "description": "Text color for subtitle text."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleFont": {
- "anyOf": [
- {
- "description": "Font name for subtitle text.",
- "type": "string"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleFontSize": {
- "anyOf": [
- {
- "description": "Font size in pixels for subtitle text.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleFontStyle": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontStyle",
- "description": "Font style for subtitle text."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleFontWeight": {
- "anyOf": [
- {
- "$ref": "#/definitions/FontWeight",
- "description": "Font weight for subtitle text. This can be either a string (e.g `\"bold\"`, `\"normal\"`) or a number (`100`, `200`, `300`, ..., `900` where `\"normal\"` = `400` and `\"bold\"` = `700`)."
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitleLineHeight": {
- "anyOf": [
- {
- "description": "Line height in pixels for multi-line subtitle text.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "subtitlePadding": {
- "anyOf": [
- {
- "description": "The padding in pixels between title and subtitle text.",
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- },
- "zindex": {
- "anyOf": [
- {
- "description": "The integer z-index indicating the layering of the title group relative to other axis, mark, and legend groups.\n\n__Default value:__ `0`.",
- "minimum": 0,
- "type": "number"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ]
- }
- },
- "type": "object"
- },
- "Baseline": {
- "enum": [
- "top",
- "middle",
- "bottom"
- ],
- "type": "string"
- },
- "BinExtent": {
- "anyOf": [
- {
- "items": {
- "type": "number"
- },
- "maxItems": 2,
- "minItems": 2,
- "type": "array"
- },
- {
- "$ref": "#/definitions/ParameterExtent"
- }
- ]
- },
- "BinParams": {
- "additionalProperties": false,
- "description": "Binning properties or boolean flag for determining whether to bin data or not.",
- "properties": {
- "anchor": {
- "description": "A value in the binned domain at which to anchor the bins, shifting the bin boundaries if necessary to ensure that a boundary aligns with the anchor value.\n\n__Default value:__ the minimum bin extent value",
- "type": "number"
- },
- "base": {
- "description": "The number base to use for automatic bin determination (default is base 10).\n\n__Default value:__ `10`",
- "type": "number"
- },
- "binned": {
- "description": "When set to `true`, Vega-Lite treats the input data as already binned.",
- "type": "boolean"
- },
- "divide": {
- "description": "Scale factors indicating allowable subdivisions. The default value is [5, 2], which indicates that for base 10 numbers (the default base), the method may consider dividing bin sizes by 5 and/or 2. For example, for an initial step size of 10, the method can check if bin sizes of 2 (= 10/5), 5 (= 10/2), or 1 (= 10/(5*2)) might also satisfy the given constraints.\n\n__Default value:__ `[5, 2]`",
- "items": {
- "type": "number"
- },
- "maxItems": 2,
- "minItems": 1,
- "type": "array"
- },
- "extent": {
- "$ref": "#/definitions/BinExtent",
- "description": "A two-element (`[min, max]`) array indicating the range of desired bin values."
- },
- "maxbins": {
- "description": "Maximum number of bins.\n\n__Default value:__ `6` for `row`, `column` and `shape` channels; `10` for other channels",
- "minimum": 2,
- "type": "number"
- },
- "minstep": {
- "description": "A minimum allowable step size (particularly useful for integer values).",
- "type": "number"
- },
- "nice": {
- "description": "If true, attempts to make the bin boundaries use human-friendly boundaries, such as multiples of ten.\n\n__Default value:__ `true`",
- "type": "boolean"
- },
- "step": {
- "description": "An exact step size to use between bins.\n\n__Note:__ If provided, options such as maxbins will be ignored.",
- "type": "number"
- },
- "steps": {
- "description": "An array of allowable step sizes to choose from.",
- "items": {
- "type": "number"
- },
- "minItems": 1,
- "type": "array"
- }
- },
- "type": "object"
- },
- "BinTransform": {
- "additionalProperties": false,
- "properties": {
- "as": {
- "anyOf": [
- {
- "$ref": "#/definitions/FieldName"
- },
- {
- "items": {
- "$ref": "#/definitions/FieldName"
- },
- "type": "array"
- }
- ],
- "description": "The output fields at which to write the start and end bin values. This can be either a string or an array of strings with two elements denoting the name for the fields for bin start and bin end respectively. If a single string (e.g., `\"val\"`) is provided, the end field will be `\"val_end\"`."
- },
- "bin": {
- "anyOf": [
- {
- "const": true,
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/BinParams"
- }
- ],
- "description": "An object indicating bin properties, or simply `true` for using default bin parameters."
- },
- "field": {
- "$ref": "#/definitions/FieldName",
- "description": "The data field to bin."
- }
- },
- "required": [
- "bin",
- "field",
- "as"
- ],
- "type": "object"
- },
- "BindCheckbox": {
- "additionalProperties": false,
- "properties": {
- "debounce": {
- "description": "If defined, delays event handling until the specified milliseconds have elapsed since the last event was fired.",
- "type": "number"
- },
- "element": {
- "$ref": "#/definitions/Element",
- "description": "An optional CSS selector string indicating the parent element to which the input element should be added. By default, all input elements are added within the parent container of the Vega view."
- },
- "input": {
- "const": "checkbox",
- "type": "string"
- },
- "name": {
- "description": "By default, the signal name is used to label input elements. This `name` property can be used instead to specify a custom label for the bound signal.",
- "type": "string"
- }
- },
- "required": [
- "input"
- ],
- "type": "object"
- },
- "BindDirect": {
- "additionalProperties": false,
- "properties": {
- "debounce": {
- "description": "If defined, delays event handling until the specified milliseconds have elapsed since the last event was fired.",
- "type": "number"
- },
- "element": {
- "anyOf": [
- {
- "$ref": "#/definitions/Element"
- },
- {
- "additionalProperties": false,
- "type": "object"
- }
- ],
- "description": "An input element that exposes a _value_ property and supports the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface, or a CSS selector string to such an element. When the element updates and dispatches an event, the _value_ property will be used as the new, bound signal value. When the signal updates independent of the element, the _value_ property will be set to the signal value and a new event will be dispatched on the element."
- },
- "event": {
- "description": "The event (default `\"input\"`) to listen for to track changes on the external element.",
- "type": "string"
- }
- },
- "required": [
- "element"
- ],
- "type": "object"
- },
- "BindInput": {
- "additionalProperties": false,
- "properties": {
- "autocomplete": {
- "description": "A hint for form autofill. See the [HTML autocomplete attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete) for additional information.",
- "type": "string"
- },
- "debounce": {
- "description": "If defined, delays event handling until the specified milliseconds have elapsed since the last event was fired.",
- "type": "number"
- },
- "element": {
- "$ref": "#/definitions/Element",
- "description": "An optional CSS selector string indicating the parent element to which the input element should be added. By default, all input elements are added within the parent container of the Vega view."
- },
- "input": {
- "description": "The type of input element to use. The valid values are `\"checkbox\"`, `\"radio\"`, `\"range\"`, `\"select\"`, and any other legal [HTML form input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).",
- "type": "string"
- },
- "name": {
- "description": "By default, the signal name is used to label input elements. This `name` property can be used instead to specify a custom label for the bound signal.",
- "type": "string"
- },
- "placeholder": {
- "description": "Text that appears in the form control when it has no value set.",
- "type": "string"
- }
- },
- "type": "object"
- },
- "BindRadioSelect": {
- "additionalProperties": false,
- "properties": {
- "debounce": {
- "description": "If defined, delays event handling until the specified milliseconds have elapsed since the last event was fired.",
- "type": "number"
- },
- "element": {
- "$ref": "#/definitions/Element",
- "description": "An optional CSS selector string indicating the parent element to which the input element should be added. By default, all input elements are added within the parent container of the Vega view."
- },
- "input": {
- "enum": [
- "radio",
- "select"
- ],
- "type": "string"
- },
- "labels": {
- "description": "An array of label strings to represent the `options` values. If unspecified, the `options` value will be coerced to a string and used as the label.",
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "name": {
- "description": "By default, the signal name is used to label input elements. This `name` property can be used instead to specify a custom label for the bound signal.",
- "type": "string"
- },
- "options": {
- "description": "An array of options to select from.",
- "items": {},
- "type": "array"
- }
- },
- "required": [
- "input",
- "options"
- ],
- "type": "object"
- },
- "BindRange": {
- "additionalProperties": false,
- "properties": {
- "debounce": {
- "description": "If defined, delays event handling until the specified milliseconds have elapsed since the last event was fired.",
- "type": "number"
- },
- "element": {
- "$ref": "#/definitions/Element",
- "description": "An optional CSS selector string indicating the parent element to which the input element should be added. By default, all input elements are added within the parent container of the Vega view."
- },
- "input": {
- "const": "range",
- "type": "string"
- },
- "max": {
- "description": "Sets the maximum slider value. Defaults to the larger of the signal value and `100`.",
- "type": "number"
- },
- "min": {
- "description": "Sets the minimum slider value. Defaults to the smaller of the signal value and `0`.",
- "type": "number"
- },
- "name": {
- "description": "By default, the signal name is used to label input elements. This `name` property can be used instead to specify a custom label for the bound signal.",
- "type": "string"
- },
- "step": {
- "description": "Sets the minimum slider increment. If undefined, the step size will be automatically determined based on the `min` and `max` values.",
- "type": "number"
- }
- },
- "required": [
- "input"
- ],
- "type": "object"
- },
- "Binding": {
- "anyOf": [
- {
- "$ref": "#/definitions/BindCheckbox"
- },
- {
- "$ref": "#/definitions/BindRadioSelect"
- },
- {
- "$ref": "#/definitions/BindRange"
- },
- {
- "$ref": "#/definitions/BindInput"
- },
- {
- "$ref": "#/definitions/BindDirect"
- }
- ]
- },
- "BinnedTimeUnit": {
- "enum": [
- "binnedyear",
- "binnedyearquarter",
- "binnedyearquartermonth",
- "binnedyearmonth",
- "binnedyearmonthdate",
- "binnedyearmonthdatehours",
- "binnedyearmonthdatehoursminutes",
- "binnedyearmonthdatehoursminutesseconds",
- "binnedyearweek",
- "binnedyearweekday",
- "binnedyearweekdayhours",
- "binnedyearweekdayhoursminutes",
- "binnedyearweekdayhoursminutesseconds",
- "binnedyeardayofyear",
- "binnedutcyear",
- "binnedutcyearquarter",
- "binnedutcyearquartermonth",
- "binnedutcyearmonth",
- "binnedutcyearmonthdate",
- "binnedutcyearmonthdatehours",
- "binnedutcyearmonthdatehoursminutes",
- "binnedutcyearmonthdatehoursminutesseconds",
- "binnedutcyearweek",
- "binnedutcyearweekday",
- "binnedutcyearweekdayhours",
- "binnedutcyearweekdayhoursminutes",
- "binnedutcyearweekdayhoursminutesseconds",
- "binnedutcyeardayofyear"
- ],
- "type": "string"
- },
- "Blend": {
- "enum": [
- null,
- "multiply",
- "screen",
- "overlay",
- "darken",
- "lighten",
- "color-dodge",
- "color-burn",
- "hard-light",
- "soft-light",
- "difference",
- "exclusion",
- "hue",
- "saturation",
- "color",
- "luminosity"
- ],
- "type": [
- "null",
- "string"
- ]
- },
- "BoxPlot": {
- "const": "boxplot",
- "type": "string"
- },
- "BoxPlotConfig": {
- "additionalProperties": false,
- "properties": {
- "box": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "extent": {
- "anyOf": [
- {
- "const": "min-max",
- "type": "string"
- },
- {
- "type": "number"
- }
- ],
- "description": "The extent of the whiskers. Available options include:\n- `\"min-max\"`: min and max are the lower and upper whiskers respectively.\n- A number representing multiple of the interquartile range. This number will be multiplied by the IQR to determine whisker boundary, which spans from the smallest data to the largest data within the range _[Q1 - k * IQR, Q3 + k * IQR]_ where _Q1_ and _Q3_ are the first and third quartiles while _IQR_ is the interquartile range (_Q3-Q1_).\n\n__Default value:__ `1.5`."
- },
- "median": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "outliers": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "rule": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "size": {
- "description": "Size of the box and median tick of a box plot",
- "type": "number"
- },
- "ticks": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- }
- },
- "type": "object"
- },
- "BoxPlotDef": {
- "additionalProperties": false,
- "properties": {
- "box": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "clip": {
- "description": "Whether a composite mark be clipped to the enclosing group’s width and height.",
- "type": "boolean"
- },
- "color": {
- "anyOf": [
- {
- "$ref": "#/definitions/Color"
- },
- {
- "$ref": "#/definitions/Gradient"
- },
- {
- "$ref": "#/definitions/ExprRef"
- }
- ],
- "description": "Default color.\n\n__Default value:__ ■ `\"#4682b4\"`\n\n__Note:__\n- This property cannot be used in a [style config](https://vega.github.io/vega-lite/docs/mark.html#style-config).\n- The `fill` and `stroke` properties have higher precedence than `color` and will override `color`."
- },
- "extent": {
- "anyOf": [
- {
- "const": "min-max",
- "type": "string"
- },
- {
- "type": "number"
- }
- ],
- "description": "The extent of the whiskers. Available options include:\n- `\"min-max\"`: min and max are the lower and upper whiskers respectively.\n- A number representing multiple of the interquartile range. This number will be multiplied by the IQR to determine whisker boundary, which spans from the smallest data to the largest data within the range _[Q1 - k * IQR, Q3 + k * IQR]_ where _Q1_ and _Q3_ are the first and third quartiles while _IQR_ is the interquartile range (_Q3-Q1_).\n\n__Default value:__ `1.5`."
- },
- "invalid": {
- "anyOf": [
- {
- "$ref": "#/definitions/MarkInvalidDataMode"
- },
- {
- "type": "null"
- }
- ],
- "description": "Invalid data mode, which defines how the marks and corresponding scales should represent invalid values (`null` and `NaN` in continuous scales *without* defined output for invalid values).\n\n- `\"filter\"` — *Exclude* all invalid values from the visualization's *marks* and *scales*. For path marks (for line, area, trail), this option will create paths that connect valid points, as if the data rows with invalid values do not exist.\n\n- `\"break-paths-filter-domains\"` — Break path marks (for line, area, trail) at invalid values. For non-path marks, this is equivalent to `\"filter\"`. All *scale* domains will *exclude* these filtered data points.\n\n- `\"break-paths-show-domains\"` — Break paths (for line, area, trail) at invalid values. Hide invalid values for non-path marks. All *scale* domains will *include* these filtered data points (for both path and non-path marks).\n\n- `\"show\"` or `null` — Show all data points in the marks and scale domains. Each scale will use the output for invalid values defined in `config.scale.invalid` or, if unspecified, by default invalid values will produce the same visual values as zero (if the scale includes zero) or the minimum value (if the scale does not include zero).\n\n- `\"break-paths-show-path-domains\"` (default) — This is equivalent to `\"break-paths-show-domains\"` for path-based marks (line/area/trail) and `\"filter\"` for non-path marks.\n\n__Note__: If any channel's scale has an output for invalid values defined in `config.scale.invalid`, all values for the scales will be considered \"valid\" since they can produce a reasonable output for the scales. Thus, fields for such channels will not be filtered and will not cause path breaks."
- },
- "median": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "opacity": {
- "description": "The opacity (value between [0,1]) of the mark.",
- "maximum": 1,
- "minimum": 0,
- "type": "number"
- },
- "orient": {
- "$ref": "#/definitions/Orientation",
- "description": "Orientation of the box plot. This is normally automatically determined based on types of fields on x and y channels. However, an explicit `orient` be specified when the orientation is ambiguous.\n\n__Default value:__ `\"vertical\"`."
- },
- "outliers": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "rule": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "size": {
- "description": "Size of the box and median tick of a box plot",
- "type": "number"
- },
- "ticks": {
- "anyOf": [
- {
- "type": "boolean"
- },
- {
- "$ref": "#/definitions/AnyMarkConfig"
- }
- ]
- },
- "type": {
- "$ref": "#/definitions/BoxPlot",
- "description": "The mark type. This could a primitive mark type (one of `\"bar\"`, `\"circle\"`, `\"square\"`, `\"tick\"`, `\"line\"`, `\"area\"`, `\"point\"`, `\"geoshape\"`, `\"rule\"`, and `\"text\"`) or a composite mark type (`\"boxplot\"`, `\"errorband\"`, `\"errorbar\"`)."
- }
- },
- "required": [
- "type"
- ],
- "type": "object"
- },
- "BrushConfig": {
- "additionalProperties": false,
- "properties": {
- "cursor": {
- "$ref": "#/definitions/Cursor",
- "description": "The mouse cursor used over the interval mark. Any valid [CSS cursor type](https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#Values) can be used."
- },
- "fill": {
- "$ref": "#/definitions/Color",
- "description": "The fill color of the interval mark.\n\n__Default value:__ `\"#333333\"`"
- },
- "fillOpacity": {
- "description": "The fill opacity of the interval mark (a value between `0` and `1`).\n\n__Default value:__ `0.125`",
- "type": "number"
- },
- "stroke": {
- "$ref": "#/definitions/Color",
- "description": "The stroke color of the interval mark.\n\n__Default value:__ `\"#ffffff\"`"
- },
- "strokeDash": {
- "description": "An array of alternating stroke and space lengths, for creating dashed or dotted lines.",
- "items": {
- "type": "number"
- },
- "type": "array"
- },
- "strokeDashOffset": {
- "description": "The offset (in pixels) with which to begin drawing the stroke dash array.",
- "type": "number"
- },
- "strokeOpacity": {
- "description": "The stroke opacity of the interval mark (a value between `0` and `1`).",
- "type": "number"
- },
- "strokeWidth": {
- "description": "The stroke width of the interval mark.",
- "type": "number"
- }
- },
- "type": "object"
- },
- "CalculateTransform": {
- "additionalProperties": false,
- "properties": {
- "as": {
- "$ref": "#/definitions/FieldName",
- "description": "The field for storing the computed formula value."
- },
- "calculate": {
- "description": "A [expression](https://vega.github.io/vega-lite/docs/types.html#expression) string. Use the variable `datum` to refer to the current data object.",
- "type": "string"
- }
- },
- "required": [
- "calculate",
- "as"
- ],
- "type": "object"
- },
- "Categorical": {
- "enum": [
- "accent",
- "category10",
- "category20",
- "category20b",
- "category20c",
- "dark2",
- "paired",
- "pastel1",
- "pastel2",
- "set1",
- "set2",
- "set3",
- "tableau10",
- "tableau20",
- "observable10"
- ],
- "type": "string"
- },
- "Color": {
- "anyOf": [
- {
- "$ref": "#/definitions/ColorName"
- },
- {
- "$ref": "#/definitions/HexColor"
- },
- {
- "type": "string"
- }
- ]
- },
- "ColorDef": {
- "$ref": "#/definitions/MarkPropDef<(Gradient|string|null)>"
- },
- "ColorName": {
- "enum": [
- "black",
- "silver",
- "gray",
- "white",
- "maroon",
- "red",
- "purple",
- "fuchsia",
- "green",
- "lime",
- "olive",
- "yellow",
- "navy",
- "blue",
- "teal",
- "aqua",
- "orange",
- "aliceblue",
- "antiquewhite",
- "aquamarine",
- "azure",
- "beige",
- "bisque",
- "blanchedalmond",
- "blueviolet",
- "brown",
- "burlywood",
- "cadetblue",
- "chartreuse",
- "chocolate",
- "coral",
- "cornflowerblue",
- "cornsilk",
- "crimson",
- "cyan",
- "darkblue",
- "darkcyan",
- "darkgoldenrod",
- "darkgray",
- "darkgreen",
- "darkgrey",
- "darkkhaki",
- "darkmagenta",
- "darkolivegreen",
- "darkorange",
- "darkorchid",
- "darkred",
- "darksalmon",
- "darkseagreen",
- "darkslateblue",
- "darkslategray",
- "darkslategrey",
- "darkturquoise",
- "darkviolet",
- "deeppink",
- "deepskyblue",
- "dimgray",
- "dimgrey",
- "dodgerblue",
- "firebrick",
- "floralwhite",
- "forestgreen",
- "gainsboro",
- "ghostwhite",
- "gold",
- "goldenrod",
- "greenyellow",
- "grey",
- "honeydew",
- "hotpink",
- "indianred",
- "indigo",
- "ivory",
- "khaki",
- "lavender",
- "lavenderblush",
- "lawngreen",
- "lemonchiffon",
- "lightblue",
- "lightcoral",
- "lightcyan",
- "lightgoldenrodyellow",
- "lightgray",
- "lightgreen",
- "lightgrey",
- "lightpink",
- "lightsalmon",
- "lightseagreen",
- "lightskyblue",
- "lightslategray",
- "lightslategrey",
- "lightsteelblue",
- "lightyellow",
- "limegreen",
- "linen",
- "magenta",
- "mediumaquamarine",
- "mediumblue",
- "mediumorchid",
- "mediumpurple",
- "mediumseagreen",
- "mediumslateblue",
- "mediumspringgreen",
- "mediumturquoise",
- "mediumvioletred",
- "midnightblue",
- "mintcream",
- "mistyrose",
- "moccasin",
- "navajowhite",
- "oldlace",
- "olivedrab",
- "orangered",
- "orchid",
- "palegoldenrod",
- "palegreen",
- "paleturquoise",
- "palevioletred",
- "papayawhip",
- "peachpuff",
- "peru",
- "pink",
- "plum",
- "powderblue",
- "rosybrown",
- "royalblue",
- "saddlebrown",
- "salmon",
- "sandybrown",
- "seagreen",
- "seashell",
- "sienna",
- "skyblue",
- "slateblue",
- "slategray",
- "slategrey",
- "snow",
- "springgreen",
- "steelblue",
- "tan",
- "thistle",
- "tomato",
- "turquoise",
- "violet",
- "wheat",
- "whitesmoke",
- "yellowgreen",
- "rebeccapurple"
- ],
- "type": "string"
- },
- "ColorScheme": {
- "anyOf": [
- {
- "$ref": "#/definitions/Categorical"
- },
- {
- "$ref": "#/definitions/SequentialSingleHue"
- },
- {
- "$ref": "#/definitions/SequentialMultiHue"
- },
- {
- "$ref": "#/definitions/Diverging"
- },
- {
- "$ref": "#/definitions/Cyclical"
- }
- ]
- },
- "Encoding": {
- "additionalProperties": false,
- "properties": {
- "angle": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Rotation angle of point and text marks."
- },
- "color": {
- "$ref": "#/definitions/ColorDef",
- "description": "Color of the marks – either fill or stroke color based on the `filled` property of mark definition. By default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`, `\"text\"`, `\"trail\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n\n__Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `color` property.\n\n_Note:_ 1) For fine-grained control over both fill and stroke colors of the marks, please use the `fill` and `stroke` channels. The `fill` or `stroke` encodings have higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified. 2) See the scale documentation for more information about customizing [color scheme](https://vega.github.io/vega-lite/docs/scale.html#scheme)."
- },
- "description": {
- "anyOf": [
- {
- "$ref": "#/definitions/StringFieldDefWithCondition"
- },
- {
- "$ref": "#/definitions/StringValueDefWithCondition"
- }
- ],
- "description": "A text description of this mark for ARIA accessibility (SVG output only). For SVG output the `\"aria-label\"` attribute will be set to this description."
- },
- "detail": {
- "anyOf": [
- {
- "$ref": "#/definitions/FieldDefWithoutScale"
- },
- {
- "items": {
- "$ref": "#/definitions/FieldDefWithoutScale"
- },
- "type": "array"
- }
- ],
- "description": "Additional levels of detail for grouping data in aggregate views and in line, trail, and area marks without mapping data to a specific visual channel."
- },
- "fill": {
- "$ref": "#/definitions/ColorDef",
- "description": "Fill color of the marks. __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `color` property.\n\n_Note:_ The `fill` encoding has higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified."
- },
- "fillOpacity": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Fill opacity of the marks.\n\n__Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `fillOpacity` property."
- },
- "href": {
- "anyOf": [
- {
- "$ref": "#/definitions/StringFieldDefWithCondition"
- },
- {
- "$ref": "#/definitions/StringValueDefWithCondition"
- }
- ],
- "description": "A URL to load upon mouse click."
- },
- "key": {
- "$ref": "#/definitions/FieldDefWithoutScale",
- "description": "A data field to use as a unique key for data binding. When a visualization’s data is updated, the key value will be used to match data elements to existing mark instances. Use a key channel to enable object constancy for transitions over dynamic data."
- },
- "latitude": {
- "$ref": "#/definitions/LatLongDef",
- "description": "Latitude position of geographically projected marks."
- },
- "latitude2": {
- "$ref": "#/definitions/Position2Def",
- "description": "Latitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`."
- },
- "longitude": {
- "$ref": "#/definitions/LatLongDef",
- "description": "Longitude position of geographically projected marks."
- },
- "longitude2": {
- "$ref": "#/definitions/Position2Def",
- "description": "Longitude-2 position for geographically projected ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`."
- },
- "opacity": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Opacity of the marks.\n\n__Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `opacity` property."
- },
- "order": {
- "anyOf": [
- {
- "$ref": "#/definitions/OrderFieldDef"
- },
- {
- "items": {
- "$ref": "#/definitions/OrderFieldDef"
- },
- "type": "array"
- },
- {
- "$ref": "#/definitions/OrderValueDef"
- },
- {
- "$ref": "#/definitions/OrderOnlyDef"
- }
- ],
- "description": "Order of the marks.\n- For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n- For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n- Otherwise, this `order` channel encodes layer order of the marks.\n\n__Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping."
- },
- "radius": {
- "$ref": "#/definitions/PolarDef",
- "description": "The outer radius in pixels of arc marks."
- },
- "radius2": {
- "$ref": "#/definitions/Position2Def",
- "description": "The inner radius in pixels of arc marks."
- },
- "shape": {
- "$ref": "#/definitions/ShapeDef",
- "description": "Shape of the mark.\n\n1. For `point` marks the supported values include: - plotting shapes: `\"circle\"`, `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`, `\"triangle-down\"`, `\"triangle-right\"`, or `\"triangle-left\"`. - the line symbol `\"stroke\"` - centered directional shapes `\"arrow\"`, `\"wedge\"`, or `\"triangle\"` - a custom [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths) (For correct sizing, custom shape paths should be defined within a square bounding box with coordinates ranging from -1 to 1 along both the x and y dimensions.)\n\n2. For `geoshape` marks it should be a field definition of the geojson data\n\n__Default value:__ If undefined, the default shape depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#point-config)'s `shape` property. (`\"circle\"` if unset.)"
- },
- "size": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Size of the mark.\n- For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n- For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n- For `\"text\"` – the text's font size.\n- Size is unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`. (Use `\"trail\"` instead of line with varying size)"
- },
- "stroke": {
- "$ref": "#/definitions/ColorDef",
- "description": "Stroke color of the marks. __Default value:__ If undefined, the default color depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `color` property.\n\n_Note:_ The `stroke` encoding has higher precedence than `color`, thus may override the `color` encoding if conflicting encodings are specified."
- },
- "strokeDash": {
- "$ref": "#/definitions/NumericArrayMarkPropDef",
- "description": "Stroke dash of the marks.\n\n__Default value:__ `[1,0]` (No dash)."
- },
- "strokeOpacity": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Stroke opacity of the marks.\n\n__Default value:__ If undefined, the default opacity depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `strokeOpacity` property."
- },
- "strokeWidth": {
- "$ref": "#/definitions/NumericMarkPropDef",
- "description": "Stroke width of the marks.\n\n__Default value:__ If undefined, the default stroke width depends on [mark config](https://vega.github.io/vega-lite/docs/config.html#mark-config)'s `strokeWidth` property."
- },
- "text": {
- "$ref": "#/definitions/TextDef",
- "description": "Text of the `text` mark."
- },
- "theta": {
- "$ref": "#/definitions/PolarDef",
- "description": "- For arc marks, the arc length in radians if theta2 is not specified, otherwise the start arc angle. (A value of 0 indicates up or “north”, increasing values proceed clockwise.)\n\n- For text marks, polar coordinate angle in radians."
- },
- "theta2": {
- "$ref": "#/definitions/Position2Def",
- "description": "The end angle of arc marks in radians. A value of 0 indicates up or “north”, increasing values proceed clockwise."
- },
- "time": {
- "$ref": "#/definitions/TimeDef"
- },
- "tooltip": {
- "anyOf": [
- {
- "$ref": "#/definitions/StringFieldDefWithCondition"
- },
- {
- "$ref": "#/definitions/StringValueDefWithCondition"
- },
- {
- "items": {
- "$ref": "#/definitions/StringFieldDef"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "description": "The tooltip text to show upon mouse hover. Specifying `tooltip` encoding overrides [the `tooltip` property in the mark definition](https://vega.github.io/vega-lite/docs/mark.html#mark-def).\n\nSee the [`tooltip`](https://vega.github.io/vega-lite/docs/tooltip.html) documentation for a detailed discussion about tooltip in Vega-Lite."
- },
- "url": {
- "anyOf": [
- {
- "$ref": "#/definitions/StringFieldDefWithCondition"
- },
- {
- "$ref": "#/definitions/StringValueDefWithCondition"
- }
- ],
- "description": "The URL of an image mark."
- },
- "x": {
- "$ref": "#/definitions/PositionDef",
- "description": "X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"` without specified `x2` or `width`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "x2": {
- "$ref": "#/definitions/Position2Def",
- "description": "X2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"width\"` for the width of the plot."
- },
- "xError": {
- "anyOf": [
- {
- "$ref": "#/definitions/SecondaryFieldDef"
- },
- {
- "$ref": "#/definitions/ValueDef"
- }
- ],
- "description": "Error value of x coordinates for error specified `\"errorbar\"` and `\"errorband\"`."
- },
- "xError2": {
- "anyOf": [
- {
- "$ref": "#/definitions/SecondaryFieldDef"
- },
- {
- "$ref": "#/definitions/ValueDef"
- }
- ],
- "description": "Secondary error value of x coordinates for error specified `\"errorbar\"` and `\"errorband\"`."
- },
- "xOffset": {
- "$ref": "#/definitions/OffsetDef",
- "description": "Offset of x-position of the marks"
- },
- "y": {
- "$ref": "#/definitions/PositionDef",
- "description": "Y coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"` without specified `y2` or `height`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- },
- "y2": {
- "$ref": "#/definitions/Position2Def",
- "description": "Y2 coordinates for ranged `\"area\"`, `\"bar\"`, `\"rect\"`, and `\"rule\"`.\n\nThe `value` of this channel can be a number or a string `\"height\"` for the height of the plot."
- },
- "yError": {
- "anyOf": [
- {
- "$ref": "#/definitions/SecondaryFieldDef"
- },
- {
- "$ref": "#/definitions/ValueDef"
- }
- ],
- "description": "Error value of y coordinates for error specified `\"errorbar\"` and `\"errorband\"`."
- },
- "yError2": {
- "anyOf": [
- {
- "$ref": "#/definitions/SecondaryFieldDef"
- },
- {
- "$ref": "#/definitions/ValueDef"
- }
- ],
- "description": "Secondary error value of y coordinates for error specified `\"errorbar\"` and `\"errorband\"`."
- },
- "yOffset": {
- "$ref": "#/definitions/OffsetDef",
- "description": "Offset of y-position of the marks"
- }
- },
- "type": "object"
- },
- "CompositeMark": {
- "anyOf": [
- {
- "$ref": "#/definitions/BoxPlot"
- },
- {
- "$ref": "#/definitions/ErrorBar"
- },
- {
- "$ref": "#/definitions/ErrorBand"
- }
- ]
- },
- "CompositeMarkDef": {
- "anyOf": [
- {
- "$ref": "#/definitions/BoxPlotDef"
- },
- {
- "$ref": "#/definitions/ErrorBarDef"
- },
- {
- "$ref": "#/definitions/ErrorBandDef"
- }
- ]
- },
- "CompositionConfig": {
- "additionalProperties": false,
- "properties": {
- "columns": {
- "description": "The number of columns to include in the view composition layout.\n\n__Default value__: `undefined` -- An infinite number of columns (a single row) will be assumed. This is equivalent to `hconcat` (for `concat`) and to using the `column` channel (for `facet` and `repeat`).\n\n__Note__:\n\n1) This property is only for:\n- the general (wrappable) `concat` operator (not `hconcat`/`vconcat`)\n- the `facet` and `repeat` operator with one field/repetition definition (without row/column nesting)\n\n2) Setting the `columns` to `1` is equivalent to `vconcat` (for `concat`) and to using the `row` channel (for `facet` and `repeat`).",
- "type": "number"
- },
- "spacing": {
- "description": "The default spacing in pixels between composed sub-views.\n\n__Default value__: `20`",
- "type": "number"
- }
- },
- "type": "object"
- },
- "ConditionalMarkPropFieldOrDatumDef": {
- "anyOf": [
- {
- "$ref": "#/definitions/ConditionalPredicate"
- },
- {
- "$ref": "#/definitions/ConditionalParameter"
- }
- ]
- },
- "ConditionalMarkPropFieldOrDatumDef": {
- "anyOf": [
- {
- "$ref": "#/definitions/ConditionalPredicate